From 8bca8c48a9a85d4347cdccb9599a521c2bf19868 Mon Sep 17 00:00:00 2001 From: Samuel Giuseppe Schlesinger Date: Fri, 23 Oct 2026 19:37:10 -0400 Subject: [PATCH] refactor(classes): make proof helpers private across the classes area MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Makes 734 theorems and definitions private in 129 modules of the classes area (#610 item 2). Statements and proofs are unchanged; only the `private` modifier and signature line breaks change, plus five redundant `@[expose]` attributes on definitions that became private. Rule: a declaration becomes private when `scripts/quality_report.py` (#604) lists it as a privatization candidate (no reference from another library module, test or abstract, not named in a module doc or README, no implicit-use attribute, not pinned by a public statement or exposed body), it is used in its own module, and its name is not API-shaped. API-shaped names stay public: `…_iff`, `mono`, `anti`, `nonneg`, `apply`, `ext`, `comm`, `congr`, `symm`, `trans` and similar, names containing a class or problem name (`mem_BPP`, `UP_subset_ModP`, `inter_mem_ParityP`), `isVerifier`, and the definitional modules of communication, decision-tree and query complexity, Kolmogorov complexity and learning, except their proof developments (`Switching`, `CanonicalTree`, `SensitivitySeparation.Internal`). Refs #610, #587 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Dvi6MU29zU9t8zYfeU51sB --- .../Communication/Discrepancy.lean | 2 +- .../Communication/Functions.lean | 2 +- .../AffineDisperser/BinaryPolynomial.lean | 26 ++--- .../AffineDisperser/Coordinates.lean | 4 +- .../Complexity/AffineDisperser/Program.lean | 13 ++- .../Classes/Alternation/Savitch.lean | 12 +- .../Complexity/Classes/Alternation/TQBF.lean | 8 +- .../Complexity/Classes/ArthurMerlin/PH.lean | 5 +- .../Classes/ArthurMerlin/SetLowerBound.lean | 2 +- .../BPP/Derandomization/Generator.lean | 4 +- .../Classes/Hierarchy/SpaceUniversal.lean | 36 +++--- .../Complexity/Classes/IP/CoinFixing.lean | 26 +++-- .../Complexity/Classes/IP/GameTree.lean | 5 +- .../Classes/IP/GraphNonIsomorphism.lean | 33 +++--- .../Complexity/Classes/IP/Repetition.lean | 3 +- .../Complexity/Classes/IP/Simulation.lean | 24 ++-- .../Complexity/Classes/IP/TQBF/Tokens.lean | 2 +- .../Complexity/Classes/IP/TQBF/Words.lean | 2 +- .../Complexity/Classes/Ladner.lean | 8 +- .../Complexity/Classes/Ladner/Basic.lean | 12 +- .../Classes/LogSpace/FirstOrder.lean | 26 ++--- .../Classes/LogSpace/FirstOrder/Formula.lean | 2 +- .../Classes/LogSpace/FirstOrder/Ordered.lean | 7 +- .../Complexity/Classes/MIP/OptimalProver.lean | 24 ++-- .../Complexity/Classes/NP/SelfReduction.lean | 18 +-- .../Complexity/Classes/NP/Witness.lean | 2 +- .../Complexity/Classes/Oracle.lean | 2 +- .../Classes/Oracle/BakerGillSolovay.lean | 10 +- .../Classes/Oracle/Deterministic.lean | 8 +- .../Complexity/Classes/Oracle/Replay.lean | 22 ++-- .../Complexity/Classes/Oracle/Simulation.lean | 2 +- .../Complexity/Classes/Oracle/TQBF.lean | 15 +-- .../Complexity/Classes/PH/Closure.lean | 2 +- .../Complexity/Classes/PH/Kannan.lean | 53 ++++----- .../Complexity/Classes/PH/KarpLipton.lean | 10 +- .../Classes/PH/SipserLautemann.lean | 2 +- .../Complexity/Classes/SPP/FewP.lean | 2 +- .../Classes/SharpP/Aggregation.lean | 4 +- .../Complexity/Classes/SharpP/Products.lean | 2 +- .../GeneralizedGeography/Membership.lean | 24 ++-- .../Space/GeneralizedGeography/Reduction.lean | 23 ++-- .../Classes/Space/TQBF/Evaluation.lean | 34 +++--- .../Classes/Space/TQBF/Formula.lean | 27 +++-- .../Classes/Space/TQBF/Membership.lean | 18 +-- .../Complexity/Classes/Space/TQBF/Prenex.lean | 10 +- .../Classes/Space/TQBF/Reduction.lean | 4 +- .../Classes/TFNP/SearchToDecision.lean | 9 +- .../Complexity/Classes/TFNP/Subclasses.lean | 10 +- .../Complexity/Classes/Toda/Counting.lean | 12 +- .../Complexity/Classes/Toda/Hierarchy.lean | 15 +-- .../Complexity/Classes/Toda/Isolation.lean | 8 +- .../Complexity/Classes/ValiantVazirani.lean | 2 +- .../Complexity/CookLevin/Correctness.lean | 12 +- .../Complexity/CookLevin/Parsimonious.lean | 16 +-- .../Complexity/Fagin/Converse.lean | 6 +- .../Complexity/Fagin/Layout.lean | 2 +- .../Complexity/Fagin/Ordered.lean | 8 +- .../Computability/Complexity/Fagin/Small.lean | 13 ++- .../Complexity/Fagin/Tableau/Semantics.lean | 10 +- .../Complexity/Fagin/Verifier.lean | 21 ++-- .../Complexity/FineGrained/Assignment.lean | 2 +- .../Complexity/FineGrained/BruteForce.lean | 12 +- .../FineGrained/Sparsification.lean | 59 +++++----- .../Complexity/HardnessEncoding/PolyTime.lean | 4 +- .../Complexity/HardnessEncoding/Program.lean | 16 +-- .../Complexity/Parameterized/VertexCover.lean | 31 +++--- .../Parameterized/VertexCover/BussKernel.lean | 48 ++++---- .../Complexity/Problems/CircuitSAT.lean | 23 ++-- .../Complexity/Problems/Coloring.lean | 2 +- .../Complexity/Problems/ExactThreeSAT.lean | 4 +- .../Complexity/Problems/GraphIsomorphism.lean | 2 +- .../Problems/Hamiltonian/Undirected.lean | 2 +- .../Complexity/Problems/IndependentSet.lean | 4 +- .../Complexity/Problems/SubsetSum.lean | 42 +++---- .../Complexity/Problems/SubsetSum/Mask.lean | 2 +- .../Complexity/Problems/TQBF/Closed.lean | 2 +- .../Complexity/Problems/TSP.lean | 5 +- .../Complexity/Problems/USTCON.lean | 4 +- .../DecisionTree/CanonicalTree.lean | 10 +- .../Computability/DecisionTree/Switching.lean | 42 +++---- Complexity/Computability/MCSP/NP.lean | 4 +- .../PCP/Approximation/Hastad.lean | 12 +- .../PCP/Approximation/IndependentSet.lean | 2 +- .../PCP/Approximation/MaxExactThreeSAT.lean | 14 ++- .../PCP/Approximation/MaxThreeSAT.lean | 18 +-- .../Computability/PCP/AssignmentTester.lean | 28 ++--- .../PCP/AssignmentTester/Selection.lean | 2 +- Complexity/Computability/PCP/Composition.lean | 2 +- .../Computability/PCP/DegreeReduction.lean | 27 +++-- .../PCP/Encoded/Constraints.lean | 2 +- .../PCP/Encoded/DegreeReduction.lean | 4 +- .../Computability/PCP/Encoded/Power.lean | 4 +- .../Computability/PCP/Encoded/Preprocess.lean | 2 +- .../PCP/Encoded/Preprocess/Programs.lean | 2 +- .../SelectedComposition/Enumeration.lean | 2 +- .../Computability/PCP/Encoded/ThreeSAT.lean | 4 +- .../PCP/Encoded/Verifier/Soundness.lean | 2 +- Complexity/Computability/PCP/Power.lean | 9 +- .../Computability/PCP/PoweringBound.lean | 4 +- Complexity/Computability/PCP/ThreeSAT.lean | 10 +- .../QueryComplexity/Relations.lean | 10 +- .../SensitivitySeparation/Internal/Basic.lean | 4 +- .../Internal/Bridge.lean | 4 +- .../Internal/Composition.lean | 2 +- .../Internal/Construction.lean | 18 +-- .../Internal/HammingBase.lean | 8 +- .../Internal/InitialPredicates.lean | 8 +- .../Internal/Iterates.lean | 6 +- .../Internal/LabelingEstimate.lean | 6 +- .../Internal/LabelingEvents.lean | 4 +- .../SensitivitySeparation/Internal/Or.lean | 2 +- .../Internal/ParameterBounds.lean | 2 +- .../Internal/RecursiveBlocks.lean | 8 +- .../Internal/RecursiveFlips.lean | 2 +- .../Internal/Reindex.lean | 6 +- .../Internal/SeparationArithmetic.lean | 6 +- .../Computability/TreeEval/Ary/CookMertz.lean | 10 +- .../Computability/TreeEval/CookMertz.lean | 4 +- .../Computability/TreeEval/Encoding.lean | 4 +- .../Computability/TreeEval/Reader/Arith.lean | 16 +-- .../TreeEval/Reader/Cert/Machine.lean | 17 +-- .../TreeEval/Reader/Cert/Offset.lean | 33 +++--- .../TreeEval/Reader/Cert/Regs.lean | 23 ++-- .../TreeEval/Reader/Cert/Residue.lean | 6 +- .../TreeEval/Reader/Cert/Step.lean | 104 ++++++++++-------- .../TreeEval/Reader/Invariant.lean | 4 +- .../Computability/TreeEval/Reader/Size.lean | 13 ++- .../Computability/USTCON/Reader/Cert.lean | 5 +- .../USTCON/Reader/Invariant.lean | 6 +- 129 files changed, 803 insertions(+), 734 deletions(-) diff --git a/Complexity/Computability/Communication/Discrepancy.lean b/Complexity/Computability/Communication/Discrepancy.lean index d6d6e5bf4..ce9dbae53 100644 --- a/Complexity/Computability/Communication/Discrepancy.lean +++ b/Complexity/Computability/Communication/Discrepancy.lean @@ -142,7 +142,7 @@ theorem abs_sum_mul_signVal_le [Fintype X] [Fintype Y] (p : Protocol X Y Bool) ( /-- The correlation under `ν` of `f` with the output of a protocol is `1 - 2 ε`, where `ε` is the probability that the protocol errs on inputs drawn from `ν`. -/ -theorem sum_mul_signVal_eq [Fintype X] [Fintype Y] (p : Protocol X Y Bool) (ν : PMF (X × Y)) +private theorem sum_mul_signVal_eq [Fintype X] [Fintype Y] (p : Protocol X Y Bool) (ν : PMF (X × Y)) (f : X → Y → Bool) : ∑ x, ∑ y, (ν (x, y)).toReal * signVal (f x y) * signVal (p.run x y) = 1 - 2 * p.distributionalError ν (fun x y b => f x y = b) := by diff --git a/Complexity/Computability/Communication/Functions.lean b/Complexity/Computability/Communication/Functions.lean index dbf741314..a94014025 100644 --- a/Complexity/Computability/Communication/Functions.lean +++ b/Complexity/Computability/Communication/Functions.lean @@ -206,7 +206,7 @@ theorem two_mul_card_dotProduct_eq_true_add [DecidableEq ι] (x : ι → Bool) : /-- The inner product is `true` on `2 ^ (k - 1) (2 ^ k - 1)` pairs of `k`-bit strings, in the form `2 c + 2 ^ k = 2 ^ k 2 ^ k`. -/ -theorem two_mul_card_dotProduct_eq_true_add_two_pow [DecidableEq ι] : +private theorem two_mul_card_dotProduct_eq_true_add_two_pow [DecidableEq ι] : 2 * #{q : (ι → Bool) × (ι → Bool) | q.1 ⬝ᵥ q.2 = true} + 2 ^ Fintype.card ι = 2 ^ Fintype.card ι * 2 ^ Fintype.card ι := by have hrow : #{q : (ι → Bool) × (ι → Bool) | q.1 ⬝ᵥ q.2 = true} = diff --git a/Complexity/Computability/Complexity/AffineDisperser/BinaryPolynomial.lean b/Complexity/Computability/Complexity/AffineDisperser/BinaryPolynomial.lean index ac199424c..3cba90c36 100644 --- a/Complexity/Computability/Complexity/AffineDisperser/BinaryPolynomial.lean +++ b/Complexity/Computability/Complexity/AffineDisperser/BinaryPolynomial.lean @@ -71,7 +71,7 @@ theorem polyOfBits_nil : polyOfBits [] = 0 := rfl theorem polyOfBits_cons (b : Bool) (l : List Bool) : polyOfBits (b :: l) = C (bitEquiv.symm b) + X * polyOfBits l := rfl -theorem polyOfBits_append (l l' : List Bool) : +private theorem polyOfBits_append (l l' : List Bool) : polyOfBits (l ++ l') = polyOfBits l + X ^ l.length * polyOfBits l' := by induction l with | nil => simp @@ -86,11 +86,11 @@ theorem polyOfBits_replicate_false (k : ℕ) : polyOfBits (List.replicate k fals | succ k ih => simp [List.replicate_succ, ih, bitEquiv_symm_false] /-- The coefficient list of the monomial `X ^ k`. -/ -theorem polyOfBits_replicate_append_true (k : ℕ) : +private theorem polyOfBits_replicate_append_true (k : ℕ) : polyOfBits (List.replicate k false ++ [true]) = X ^ k := by simp [polyOfBits_append, bitEquiv_symm_true] -theorem polyOfBits_zipWith_xor {l l' : List Bool} (h : l.length = l'.length) : +private theorem polyOfBits_zipWith_xor {l l' : List Bool} (h : l.length = l'.length) : polyOfBits (l.zipWith xor l') = polyOfBits l + polyOfBits l' := by induction l generalizing l' with | nil => cases l' <;> simp_all @@ -121,7 +121,7 @@ theorem polyOfBits_eq_zero_iff {l : List Bool} : polyOfBits l = 0 ↔ ∀ b ∈ rw [h, bitEquiv_symm_false] simp -theorem degree_polyOfBits_lt (l : List Bool) : (polyOfBits l).degree < l.length := by +private theorem degree_polyOfBits_lt (l : List Bool) : (polyOfBits l).degree < l.length := by induction l with | nil => simp | cons b l ih => @@ -138,7 +138,7 @@ theorem degree_polyOfBits_lt (l : List Bool) : (polyOfBits l).degree < l.length omega /-- Dropping a top coefficient that is zero does not change the polynomial. -/ -theorem polyOfBits_take_of_getD {l : List Bool} {m : ℕ} (hl : l.length = m + 1) +private theorem polyOfBits_take_of_getD {l : List Bool} {m : ℕ} (hl : l.length = m + 1) (htop : l.getD m false = false) : polyOfBits (l.take m) = polyOfBits l := by conv_rhs => rw [← List.take_append_drop m l] have hdrop : l.drop m = [false] := by @@ -148,7 +148,7 @@ theorem polyOfBits_take_of_getD {l : List Bool} {m : ℕ} (hl : l.length = m + 1 rw [hdrop, polyOfBits_append] simp [bitEquiv_symm_false] -theorem aeval_polyOfBits {A : Type*} [CommSemiring A] [Algebra (ZMod 2) A] (α : A) +private theorem aeval_polyOfBits {A : Type*} [CommSemiring A] [Algebra (ZMod 2) A] (α : A) (l : List Bool) : aeval α (polyOfBits l) = ∑ d ∈ Finset.range l.length, bitEquiv.symm (l.getD d false) • α ^ d := by @@ -204,12 +204,12 @@ def mulXMod (g r : List Bool) : List Bool := (if (false :: r).getD (g.length - 1) false then (false :: r).zipWith xor g else false :: r).take (g.length - 1) -theorem length_mulXMod (l r : List Bool) (h : r.length = l.length) : +private theorem length_mulXMod (l r : List Bool) (h : r.length = l.length) : (mulXMod (l ++ [true]) r).length = l.length := by unfold mulXMod split_ifs <;> simp [h] -theorem mk_polyOfBits_mulXMod (l r : List Bool) (h : r.length = l.length) : +private theorem mk_polyOfBits_mulXMod (l r : List Bool) (h : r.length = l.length) : AdjoinRoot.mk (polyOfBits (l ++ [true])) (polyOfBits (mulXMod (l ++ [true]) r)) = AdjoinRoot.mk (polyOfBits (l ++ [true])) (X * polyOfBits r) := by have hlen : (l ++ [true]).length - 1 = l.length := by simp @@ -276,7 +276,7 @@ private theorem modStep_foldl (l f p a : List Bool) (hp : p.length = l.length) simp only [map_add, map_mul, map_zero] ring -theorem length_modBits (l f : List Bool) : (modBits (l ++ [true]) f).length = l.length := by +private theorem length_modBits (l f : List Bool) : (modBits (l ++ [true]) f).length = l.length := by have hlen : (l ++ [true]).length - 1 = l.length := by simp unfold modBits rw [hlen] @@ -303,7 +303,7 @@ theorem mk_polyOfBits_modBits (l f : List Bool) : simp -theorem polyOfBits_append_true_ne_zero (l : List Bool) : polyOfBits (l ++ [true]) ≠ 0 := by +private theorem polyOfBits_append_true_ne_zero (l : List Bool) : polyOfBits (l ++ [true]) ≠ 0 := by rw [Ne, polyOfBits_eq_zero_iff] intro h exact Bool.true_eq_false.mp (h true (by simp)) @@ -323,12 +323,12 @@ theorem modBits_all_false_iff (l f : List Bool) : private theorem monic_of_ne_zero {q : (ZMod 2)[X]} (hq : q ≠ 0) : q.Monic := (by decide : ∀ c : ZMod 2, c ≠ 0 → c = 1) _ (leadingCoeff_ne_zero.2 hq) -theorem natDegree_polyOfCode_eq_log (m : ℕ) : (polyOfCode m).natDegree = Nat.log 2 m := by +private theorem natDegree_polyOfCode_eq_log (m : ℕ) : (polyOfCode m).natDegree = Nat.log 2 m := by rcases eq_or_ne m 0 with rfl | hm · simp · exact natDegree_polyOfCode hm -theorem polyOfCode_one : polyOfCode 1 = 1 := by +private theorem polyOfCode_one : polyOfCode 1 = 1 := by rw [← polyOfBits_bits, Nat.one_bits] simp [bitEquiv_symm_true] @@ -436,7 +436,7 @@ polynomial with coefficient list `g`. -/ def powerTable (g : List Bool) : List (List Bool) := (List.range (2 * (g.length - 1))).map fun e => modBits g (List.replicate e false ++ [true]) -theorem length_powerTable (g : List Bool) : (powerTable g).length = 2 * (g.length - 1) := by +private theorem length_powerTable (g : List Bool) : (powerTable g).length = 2 * (g.length - 1) := by simp [powerTable] /-- At a root `α` of the polynomial with coefficient list `l ++ [true]`, the power `α ^ e`, diff --git a/Complexity/Computability/Complexity/AffineDisperser/Coordinates.lean b/Complexity/Computability/Complexity/AffineDisperser/Coordinates.lean index 962524b7d..78aec860a 100644 --- a/Complexity/Computability/Complexity/AffineDisperser/Coordinates.lean +++ b/Complexity/Computability/Complexity/AffineDisperser/Coordinates.lean @@ -76,7 +76,7 @@ theorem repr_fieldOfBits (B : Basis (Fin n) (ZMod 2) F) (a : List Bool) (u : Fin theorem fieldOfBits_nil (B : Basis (Fin n) (ZMod 2) F) : fieldOfBits B [] = 0 := by simp [fieldOfBits] -theorem bitEquiv_symm_foldl_xor (l : List Bool) : +private theorem bitEquiv_symm_foldl_xor (l : List Bool) : bitEquiv.symm (l.foldl xor false) = (l.map bitEquiv.symm).sum := by rw [← map_list_sum] congr 1 @@ -287,7 +287,7 @@ private theorem getD_take_drop (x : List Bool) {n u : ℕ} (hu : u < n) (i : ℕ rw [List.getD_eq_getElem?_getD, List.getD_eq_getElem?_getD, List.getElem?_take_of_lt hu, List.getElem?_drop] -theorem readField_blockPos (B : Basis (Fin n) (ZMod 2) F) {r N : ℕ} (h : r * n ≤ N) +private theorem readField_blockPos (B : Basis (Fin n) (ZMod 2) F) {r N : ℕ} (h : r * n ≤ N) (x : List Bool) (i : Fin r) : readField B (blockPos h) (ofList N x) i = fieldOfBits B ((x.drop (n * i)).take n) := by refine Finset.sum_congr rfl fun u _ => ?_ diff --git a/Complexity/Computability/Complexity/AffineDisperser/Program.lean b/Complexity/Computability/Complexity/AffineDisperser/Program.lean index 3661fec5e..d2f0ddd46 100644 --- a/Complexity/Computability/Complexity/AffineDisperser/Program.lean +++ b/Complexity/Computability/Complexity/AffineDisperser/Program.lean @@ -84,7 +84,7 @@ def monomialTable (ms : List ℕ) (R : List (List (List Bool))) : List (List (Li (List.range ms.prod).map fun v => monomialBit ms R u w v /-- The mixed-radix digits are the components of `finPiFinEquiv.symm`. -/ -theorem mixedDigit_eq (ms : List ℕ) (u : Fin (∏ i, ms.get i)) (i : Fin ms.length) : +private theorem mixedDigit_eq (ms : List ℕ) (u : Fin (∏ i, ms.get i)) (i : Fin ms.length) : mixedDigit ms u i = (finPiFinEquiv.symm u i : ℕ) := by have hprod : ∏ j : Fin i, ms.get (Fin.castLE i.is_lt.le j) = (ms.take i).prod := by rw [← List.prod_ofFn] @@ -109,7 +109,7 @@ private theorem bitEquiv_symm_all (k : ℕ) (p : ℕ → Bool) : rw [Bool.not_eq_true] at hpi simp [hpi] -theorem tableEntry_monomialTable {ms : List ℕ} {R : List (List (List Bool))} {u w : ℕ} +private theorem tableEntry_monomialTable {ms : List ℕ} {R : List (List (List Bool))} {u w : ℕ} (hu : u < ms.prod) (hw : w < ms.prod) : tableEntry (monomialTable ms R) u w = (List.range ms.prod).map (monomialBit ms R u w) := by simp [tableEntry, monomialTable, List.getD_eq_getElem?_getD, hu, hw] @@ -190,13 +190,14 @@ theorem aeval_binaryRoot_degreePrime (N : ℕ) (j : Fin (degreePrimes N).length) exact minpoly.aeval _ _ /-- The basis of the explicit disperser is the monomial basis in the roots `binaryRoot`. -/ -theorem explicitBasis_eq_rootBasis (N : ℕ) : +private theorem explicitBasis_eq_rootBasis (N : ℕ) : explicitBasis N = rootBasis N (fun j => binaryRoot (degreePrime N j) (fieldDegree N)) (aeval_binaryRoot_degreePrime N) := rfl /-- The explicit table is the multiplication table of the monomial basis in any roots. -/ -theorem isMulTable_explicitTable (N : ℕ) (α : (j : Fin (degreePrimes N).length) → ExplicitField N) +private theorem isMulTable_explicitTable (N : ℕ) + (α : (j : Fin (degreePrimes N).length) → ExplicitField N) (hα : ∀ j, aeval (α j) (leastIrreducible (degreePrime N j)) = 0) : IsMulTable ((rootBasis N α hα).reindex finPiFinEquiv) (explicitTable N) := by refine isMulTable_monomialTable _ _ _ _ _ fun i e he => ?_ @@ -228,7 +229,7 @@ theorem isMulTable_explicitTable (N : ℕ) (α : (j : Fin (degreePrimes N).lengt omit [FiniteDimensional (ZMod 2) F] in /-- Reindexing the basis and the reading positions together does not change `traceSymBits`. -/ -theorem traceSymBits_reindex {ι ι' : Type*} [Fintype ι] [Fintype ι'] {r t N : ℕ} (μ : F) +private theorem traceSymBits_reindex {ι ι' : Type*} [Fintype ι] [Fintype ι'] {r t N : ℕ} (μ : F) (b : Basis ι (ZMod 2) F) (e : ι ≃ ι') (pos : Fin r × ι' → Fin N) (x : BitString N) : traceSymBits μ r t (b.reindex e) pos x = traceSymBits μ r t b (fun q => pos (q.1, e q.2)) x := by @@ -241,7 +242,7 @@ theorem traceSymBits_reindex {ι ι' : Type*} [Fintype ι] [Fintype ι'] {r t N /-- The coordinate computation with the explicit table is `traceSymBits` in the monomial basis in any roots `α` of the least-code irreducible polynomials, read on the first `N` bits of `x` (missing bits are zero). -/ -theorem traceSymCoords_explicitTable_eq_traceSymBits (N : ℕ) +private theorem traceSymCoords_explicitTable_eq_traceSymBits (N : ℕ) (α : (j : Fin (degreePrimes N).length) → ExplicitField N) (hα : ∀ j, aeval (α j) (leastIrreducible (degreePrime N j)) = 0) (x : List Bool) : traceSymCoords (explicitTable N) (numBlocks N) (symDegree N) x = diff --git a/Complexity/Computability/Complexity/Classes/Alternation/Savitch.lean b/Complexity/Computability/Complexity/Classes/Alternation/Savitch.lean index a9f7ec60e..fb012a949 100644 --- a/Complexity/Computability/Complexity/Classes/Alternation/Savitch.lean +++ b/Complexity/Computability/Complexity/Classes/Alternation/Savitch.lean @@ -115,16 +115,16 @@ def midpointMoves (w : ℕ) (z : List Bool) : List Bool := (List.range w).map fun j => z.getD (2 * j) false /-- A midpoint has width `w`. -/ -theorem length_midpointMoves (w : ℕ) (z : List Bool) : (midpointMoves w z).length = w := by +private theorem length_midpointMoves (w : ℕ) (z : List Bool) : (midpointMoves w z).length = w := by simp [midpointMoves] /-- The first round of a level writes the first bit of the midpoint. -/ -theorem midpointMoves_cons_cons (w : ℕ) (x y : Bool) (z : List Bool) : +private theorem midpointMoves_cons_cons (w : ℕ) (x y : Bool) (z : List Bool) : midpointMoves (w + 1) (x :: y :: z) = x :: midpointMoves w z := by simp [midpointMoves, List.range_succ_eq_map, Nat.mul_succ] /-- The midpoint only reads the first `2 * w` moves. -/ -theorem midpointMoves_take {w n : ℕ} (hn : 2 * w ≤ n) (z : List Bool) : +private theorem midpointMoves_take {w n : ℕ} (hn : 2 * w ≤ n) (z : List Bool) : midpointMoves w (z.take n) = midpointMoves w z := by refine List.map_congr_left fun j hj => ?_ rw [List.mem_range] at hj @@ -147,7 +147,7 @@ def midpointGame (edge : List Bool → List Bool → Bool) (w : ℕ) : variable {edge : List Bool → List Bool → Bool} {w : ℕ} /-- The game at level `i` reads only its first `2 * ((w + 1) * i)` moves. -/ -theorem midpointGame_take (i : ℕ) (u v z : List Bool) : +private theorem midpointGame_take (i : ℕ) (u v z : List Bool) : midpointGame edge w i u v (z.take (2 * ((w + 1) * i))) = midpointGame edge w i u v z := by induction i generalizing u v z with | zero => rfl @@ -167,7 +167,7 @@ theorem midpointGame_take (i : ℕ) (u v z : List Bool) : simp only [midpointGame, hget, hmid, hdrop, ih] /-- The existential player chooses a midpoint in `w` rounds. -/ -theorem alternation_midpointMoves (j : ℕ) {ns : List ℕ} : +private theorem alternation_midpointMoves (j : ℕ) {ns : List ℕ} : ∀ R : List Bool → List Bool → Prop, Alternation true (List.replicate (2 * j) 1 ++ ns) (fun z => R (midpointMoves j z) (z.drop (2 * j))) ↔ @@ -191,7 +191,7 @@ theorem alternation_midpointMoves (j : ℕ) {ns : List ℕ} : · exact ⟨x, fun _ => ⟨m, by simpa using hm, h⟩⟩ /-- The universal player chooses a half in one round. -/ -theorem alternation_half {ns : List ℕ} (S : Bool → List Bool → Prop) : +private theorem alternation_half {ns : List ℕ} (S : Bool → List Bool → Prop) : Alternation true (1 :: 1 :: ns) (fun z => S (z.getD 1 false) (z.drop 2)) ↔ ∀ d, Alternation true ns (S d) := by rw [alternation_true_one_cons] diff --git a/Complexity/Computability/Complexity/Classes/Alternation/TQBF.lean b/Complexity/Computability/Complexity/Classes/Alternation/TQBF.lean index 21cfbbc58..987e4bd8a 100644 --- a/Complexity/Computability/Complexity/Classes/Alternation/TQBF.lean +++ b/Complexity/Computability/Complexity/Classes/Alternation/TQBF.lean @@ -132,7 +132,7 @@ theorem updates_of_notMem {σ : V → Bool} {vs : List V} {x : V} (hx : x ∉ vs rw [updates, ih hx.2, Function.update_of_ne hx.1] /-- Updating distinct variables by as many values sets them to these values. -/ -theorem map_updates {σ : V → Bool} {vs : List V} (hvs : vs.Nodup) {bs : List Bool} +private theorem map_updates {σ : V → Bool} {vs : List V} (hvs : vs.Nodup) {bs : List Bool} (hlen : bs.length = vs.length) : vs.map (updates σ vs bs) = bs := by induction vs generalizing σ bs with | nil => exact (List.length_eq_zero_iff.mp hlen).symm @@ -233,7 +233,7 @@ blocks of level `0`. -/ def gamePairs (w : ℕ) : List (ℕ × ℕ) := (List.range w).map fun i => (certVar w (2 * i), certVar w (2 * i + 1)) -theorem length_gamePairs (w : ℕ) : (gamePairs w).length = w := by +private theorem length_gamePairs (w : ℕ) : (gamePairs w).length = w := by simp [gamePairs] /-- The variables of the moves are those of the blocks of level `0`. -/ @@ -336,7 +336,7 @@ theorem gameReduce_mem_TQBF_iff {V : α × List Bool → Bool} {kV : ℕ} {State def roundTokens (w i : ℕ) : List (QBF.Kind × ℕ) := [(.ex, certVar w (2 * i))] ++ [(.all, certVar w (2 * i + 1))] -theorem tokens_gameFormula {k : ℕ} {State : Type} [Fintype State] +private theorem tokens_gameFormula {k : ℕ} {State : Type} [Fintype State] (tab : CNF (CookLevin.Var k State)) (w : ℕ) : (gameFormula tab w).tokens = (List.range w).flatMap (roundTokens w) ++ (baseFormula tab w).tokens := by @@ -396,7 +396,7 @@ variable {α : Type} {enc : α ↪ List Bool} {p : Polynomial ℕ} {V : α × Li {A : Set α} /-- **Games with a polynomial-time winning condition reduce to `TQBF`.** -/ -theorem IsGameVerifier.polyTimeReducible +private theorem IsGameVerifier.polyTimeReducible (hV : ComputableTidilyInPolyTime V (encPair enc encBits) encBool) (h : IsGameVerifier enc p V A) : PolyTimeReducible enc encQBF A TQBF := by obtain ⟨tV, sV, htV, -, kV, StateV, hfiniteV, tmV, htmV⟩ := hV diff --git a/Complexity/Computability/Complexity/Classes/ArthurMerlin/PH.lean b/Complexity/Computability/Complexity/Classes/ArthurMerlin/PH.lean index 2c648a50d..229177818 100644 --- a/Complexity/Computability/Complexity/Classes/ArthurMerlin/PH.lean +++ b/Complexity/Computability/Complexity/Classes/ArthurMerlin/PH.lean @@ -103,7 +103,8 @@ theorem computableTidilyInPolyTime_sigmaTwoVerifier {W : α × List Bool → Boo /-- On a proof followed by the shifts and then a random string `r`, the `Σ₂` verifier accepts iff `W` accepts the proof with `r` xor some shift. -/ -theorem sigmaTwoVerifier_append_ofFn {q k p : Polynomial ℕ} {W : α × List Bool → Bool} {a : α} +private theorem sigmaTwoVerifier_append_ofFn {q k p : Polynomial ℕ} {W : α × List Bool → Bool} + {a : α} {w : List Bool} (hw : w.length = q.eval (enc a).length + k.eval (enc a).length * p.eval (enc a).length) (r : BitString (p.eval (enc a).length)) : @@ -193,7 +194,7 @@ theorem computableTidilyInPolyTime_piTwoVerifier {W : α × List Bool → Bool} /-- On the shifts followed by any word `v`, the `Π₂` verifier accepts iff `W` accepts, for each shift, the first `p(n)` bits of `v` xor the shift with the corresponding reply read from the rest of `v`. -/ -theorem piTwoVerifier_append {k p q : Polynomial ℕ} {W : α × List Bool → Bool} {a : α} +private theorem piTwoVerifier_append {k p q : Polynomial ℕ} {W : α × List Bool → Bool} {a : α} {u : List Bool} (hu : u.length = k.eval (enc a).length * p.eval (enc a).length) (v : List Bool) : piTwoVerifier enc k p q W (a, u ++ v) = true ↔ diff --git a/Complexity/Computability/Complexity/Classes/ArthurMerlin/SetLowerBound.lean b/Complexity/Computability/Complexity/Classes/ArthurMerlin/SetLowerBound.lean index 8f883dc2d..ad3214b53 100644 --- a/Complexity/Computability/Complexity/Classes/ArthurMerlin/SetLowerBound.lean +++ b/Complexity/Computability/Complexity/Classes/ArthurMerlin/SetLowerBound.lean @@ -172,7 +172,7 @@ theorem computableTidilyInPolyTime_verifier {N c m T : Polynomial ℕ} {ℓ : α /-- On a seed, an element and five certificates, the verifier accepts exactly when the blocks of the element have accepted certificates, the padding starts with `ℓ` bits `false` and the affine hash given by the seed sends the element to zero. -/ -theorem verifier_ofFn_append {N c m T : Polynomial ℕ} {ℓ : α → ℕ} {R : α × List Bool → Bool} +private theorem verifier_ofFn_append {N c m T : Polynomial ℕ} {ℓ : α → ℕ} {R : α × List Bool → Bool} (a : α) (r : BitString (m.eval (enc a).length * (5 * N.eval (enc a).length + T.eval (enc a).length) + m.eval (enc a).length)) (e : BitString (5 * N.eval (enc a).length + T.eval (enc a).length)) diff --git a/Complexity/Computability/Complexity/Classes/BPP/Derandomization/Generator.lean b/Complexity/Computability/Complexity/Classes/BPP/Derandomization/Generator.lean index b93c2f687..90e204d65 100644 --- a/Complexity/Computability/Complexity/Classes/BPP/Derandomization/Generator.lean +++ b/Complexity/Computability/Complexity/Classes/BPP/Derandomization/Generator.lean @@ -183,14 +183,14 @@ open Turing.MultiTapeTM.ComputableTidilyInPolyTime variable {γ : Type} {encIn : γ ↪ List Bool} /-- Counting the common ones of two masks is polynomial-time. -/ -theorem computableTidilyInPolyTime_overlapCount : +private theorem computableTidilyInPolyTime_overlapCount : ComputableTidilyInPolyTime (fun p : List Bool × List Bool => overlapCount p.1 p.2) (encPair encBits encBits) encUnary := by unfold overlapCount fun_prop /-- Reading the bits of a word at the ones of a mask is polynomial-time. -/ -theorem computableTidilyInPolyTime_restrictMask : +private theorem computableTidilyInPolyTime_restrictMask : ComputableTidilyInPolyTime (fun p : List Bool × List Bool => restrictMask p.1 p.2) (encPair encBits encBits) encBits := by unfold restrictMask diff --git a/Complexity/Computability/Complexity/Classes/Hierarchy/SpaceUniversal.lean b/Complexity/Computability/Complexity/Classes/Hierarchy/SpaceUniversal.lean index 87832e634..e13d57c63 100644 --- a/Complexity/Computability/Complexity/Classes/Hierarchy/SpaceUniversal.lean +++ b/Complexity/Computability/Complexity/Classes/Hierarchy/SpaceUniversal.lean @@ -132,14 +132,14 @@ public theorem budgetStep_iterate (i : ℕ) : ∃ j ≤ i, · exact ⟨j, by omega, rfl, hb⟩ /-- The run within the budget keeps at most two symbols of the output. -/ -public lemma length_budgetStep_iterate_le (i : ℕ) : +private lemma length_budgetStep_iterate_le (i : ℕ) : ((budgetStep d x b)^[i] (init d, [])).2.length ≤ 2 := by obtain ⟨j, -, heq, -⟩ := budgetStep_iterate d x b i rw [heq, List.length_take] exact min_le_left _ _ /-- The symbols of the output kept by the run within the budget are numbers of the description. -/ -public lemma le_of_mem_budgetStep_iterate (i : ℕ) {o : ℕ} +private lemma le_of_mem_budgetStep_iterate (i : ℕ) {o : ℕ} (ho : o ∈ ((budgetStep d x b)^[i] (init d, [])).2) : o ≤ descLen d := by obtain ⟨j, -, heq, -⟩ := budgetStep_iterate d x b i rw [heq] at ho @@ -147,7 +147,7 @@ public lemma le_of_mem_budgetStep_iterate (i : ℕ) {o : ℕ} /-- **Within the budget**, the run is the run of the simulation, with the first two symbols of its output. -/ -public theorem budgetStep_iterate_of_le {t : ℕ} +private theorem budgetStep_iterate_of_le {t : ℕ} (hb : ∀ j < t, (eCfg (run d x (j + 1))).length ≤ b) : (budgetStep d x b)^[t] (init d, []) = (run d x t, (simulate d x t).1.take 2) := by induction t with @@ -192,28 +192,28 @@ public theorem budgetedUniversal_desc {k : ℕ} {Symbol S : Type} [Fintype S] [F public abbrev SSt := St × ℕ × List ℕ /-- The encoding of the states of the fold within a budget, with the budget in unary. -/ -public abbrev eSSt : SSt ↪ List Bool := encPair eSt (encPair encUnary (encList encUnary)) +private abbrev eSSt : SSt ↪ List Bool := encPair eSt (encPair encUnary (encList encUnary)) /-- The initial state: the initial state of the in-place fold, the budget and no output. -/ -@[expose] public def foldInitS (i : Desc × List ℕ × ℕ × ℕ) : SSt := +private def foldInitS (i : Desc × List ℕ × ℕ × ℕ) : SSt := (foldInit (i.1, i.2.1, i.2.2.1), i.2.2.2, []) /-- A round: one event of the countdown, as in the in-place fold. -/ -@[expose] public def foldNextS (p : SSt × Bool) : SSt := (foldNext (p.1.1, p.2), p.1.2) +private def foldNextS (p : SSt × Bool) : SSt := (foldNext (p.1.1, p.2), p.1.2) /-- The end of a pass within the budget: the step of the in-place fold if the configuration it reaches is encoded within the budget, keeping the first two symbols of the output; otherwise the configuration stays, one step less is left and the countdown is reset to the input head. -/ -@[expose] public def foldEndS (s : SSt) : SSt := +private def foldEndS (s : SSt) : SSt := if (eCfg (stepAt s.1).1).length ≤ s.2.1 then (foldEnd s.1, s.2.1, (s.2.2 ++ (stepAt s.1).2.toList).take 2) else (((s.1.1.1, s.1.1.2), (s.1.2.1 - 1, s.1.1.2.inputPos, 0)), s.2) /-- Whether another pass follows. -/ -@[expose] public def foldContS (s : SSt) : Bool := foldCont s.1 +private def foldContS (s : SSt) : Bool := foldCont s.1 /-- The result: the first two symbols of the output, and whether the machine has halted. -/ -@[expose] public def foldFinishS (s : SSt) : List ℕ × Bool := (s.2.2, s.1.1.2.state.isNone) +private def foldFinishS (s : SSt) : List ℕ × Bool := (s.2.2, s.1.1.2.state.isNone) lemma streamState_foldNextS (s : SSt) (l : List Bool) (j : ℕ) : streamState s foldNextS l j = ((s.1.1, (s.1.2.1, (l.take j).foldl scan s.1.2.2)), s.2) := @@ -228,7 +228,7 @@ lemma stepAt_scan' (c : SCfg) (r : ℕ) : /-- **The passes within the budget** follow the run within the budget, as long as steps are left. -/ -public theorem passState_foldS (t i : ℕ) : +private theorem passState_foldS (t i : ℕ) : passState (foldInitS (d, x, t, b)) foldNextS foldEndS (events x) i = (((d, ((budgetStep d x b)^[min i t] (init d, [])).1), (t - i, ((budgetStep d x b)^[min i t] (init d, [])).1.inputPos, 0)), b, @@ -282,7 +282,7 @@ lemma inTr_run_symbol (n : ℕ) (v : List Bool) : simp [tok, List.replicate_succ] /-- The events of the encoded input of `budgetedUniversal` are the events of the symbols of `x`. -/ -public theorem events_eInS (t : ℕ) : inTr.events (eInS (d, x, t, b)) = events x := by +private theorem events_eInS (t : ℕ) : inTr.events (eInS (d, x, t, b)) = events x := by have hx : ∀ v, inTr.run .marker (doubled (encList encUnary x) ++ v) = ((inTr.run .marker v).1, events x ++ (inTr.run .marker v).2) := by intro v @@ -400,7 +400,7 @@ binary, the largest symbol of the input, the budget in unary and two symbols of i.2.1.foldr max 0))) + 1 + (2 * i.2.2.2 + 1 + 2 * (2 * descLen i.1 + 1)) /-- **The size of the states** of the fold within the budget. -/ -public lemma length_eSSt_le (t i j : ℕ) : +private lemma length_eSSt_le (t i j : ℕ) : (eSSt (streamState (passState (foldInitS (d, x, t, b)) foldNextS foldEndS (events x) i) foldNextS (events x) j)).length ≤ budgetSpace (d, x, t, b) := by rw [passState_foldS, streamState_foldNextS] @@ -464,7 +464,7 @@ lemma keepTwo_deg : ComputableTidilyInDegree exact (take_two_deg.comp happ).mono /-- The initial state, in the space of the description, the number of steps and the budget. -/ -public lemma foldInitS_inO : ComputableTidilyInO foldInitS eInS eSSt +private lemma foldInitS_inO : ComputableTidilyInO foldInitS eInS eSSt (fun i => (eInS i).length + ((encPair eDesc (encPair encNat encUnary) (i.1, i.2.2)).length + 1) ^ 2) fun i => (encPair eDesc (encPair encNat encUnary) (i.1, i.2.2)).length + 1 := by @@ -485,7 +485,7 @@ public lemma foldInitS_inO : ComputableTidilyInO foldInitS eInS eSSt nlinarith /-- A round of the countdown. -/ -public lemma foldNextS_inO : ComputableTidilyInO foldNextS (encPair eSSt encBool) eSSt +private lemma foldNextS_inO : ComputableTidilyInO foldNextS (encPair eSSt encBool) eSSt (fun p => ((encPair eSSt encBool p).length + 1) ^ 2) fun p => (encPair eSSt encBool p).length + 1 := by have h₁ := fst eSSt encBool @@ -498,7 +498,7 @@ public lemma foldNextS_inO : ComputableTidilyInO foldNextS (encPair eSSt encBool nlinarith /-- Whether another pass follows. -/ -public lemma foldContS_inO : ComputableTidilyInO foldContS eSSt encBool +private lemma foldContS_inO : ComputableTidilyInO foldContS eSSt encBool (fun s => ((eSSt s).length + 1) ^ 3) fun s => (eSSt s).length + 1 := by have h := foldCont_inO.comp (fst eSt (encPair encUnary (encList encUnary))) refine (h.of_enc_eq (g := foldContS) fun s => rfl).mono 2 (fun s => ?_) fun s => ?_ @@ -511,7 +511,7 @@ public lemma foldContS_inO : ComputableTidilyInO foldContS eSSt encBool omega /-- The result: the first two symbols of the output, and whether the machine has halted. -/ -public lemma foldFinishS_inO : ComputableTidilyInO foldFinishS eSSt eOut +private lemma foldFinishS_inO : ComputableTidilyInO foldFinishS eSSt eOut (fun s => ((eSSt s).length + 1) ^ 3) fun s => (eSSt s).length + 1 := by have h₁ := fst eSt (encPair encUnary (encList encUnary)) have h₂ := snd eSt (encPair encUnary (encList encUnary)) @@ -584,7 +584,7 @@ lemma budgetTest_inO : ComputableTidilyInO /-- The end of a pass within the budget: the step of the in-place fold, the budget test on the length of the configuration it reaches, and either branch. -/ -public lemma foldEndS_inO : ComputableTidilyInO foldEndS eSSt eSSt +private lemma foldEndS_inO : ComputableTidilyInO foldEndS eSSt eSSt (fun s => ((eSSt s).length + 1) ^ 3) fun s => (eSSt s).length + 1 := by have h₁ := fst eSt (encPair encUnary (encList encUnary)) have h₂ := snd eSt (encPair encUnary (encList encUnary)) @@ -761,7 +761,7 @@ public theorem computableTidilyInTimeAndSpace_budgetedUniversal : ∃ c, /-- The initial configuration is encoded within `11 * descLen d + 6` bits: the initial state, the input head at `1` and blank work tapes. -/ -public lemma length_eCfg_init_le : (eCfg (init d)).length ≤ 11 * descLen d + 6 := by +private lemma length_eCfg_init_le : (eCfg (init d)).length ≤ 11 * descLen d + 6 := by have hq : d.q₀ ≤ descLen d := by simp only [descLen, eDesc_apply, length_encPair, encUnary_apply, List.length_replicate]; omega have hk : d.tapes ≤ descLen d := by diff --git a/Complexity/Computability/Complexity/Classes/IP/CoinFixing.lean b/Complexity/Computability/Complexity/Classes/IP/CoinFixing.lean index f9fdfe01d..4ad274c96 100644 --- a/Complexity/Computability/Complexity/Classes/IP/CoinFixing.lean +++ b/Complexity/Computability/Complexity/Classes/IP/CoinFixing.lean @@ -88,7 +88,8 @@ local notation "handler" o => ProbOracleComp.handler (fun n => StateT.lift (ProbComp.unifOracle n)) o /-- An instruction with a fixed coin makes the requests of `coinStep`. -/ -theorem run_interpret_finiteStep_pure (t : ℕ) (cfg : FiniteConfig k Bool Control Unit) (b : Bool) +private theorem run_interpret_finiteStep_pure (t : ℕ) (cfg : FiniteConfig k Bool Control Unit) + (b : Bool) (s : S) : (OracleComp.interpret (handler oracle) (M.finiteStep (fun choices => choices <$> pure b) (fun op w => List.take t <$> ProbOracleComp.query (op, w)) cfg)).run s = @@ -105,7 +106,8 @@ theorem run_interpret_finiteStep_pure (t : ℕ) (cfg : FiniteConfig k Bool Contr OracleComp.interpret_query, OracleComp.interpret_pure] /-- Instructions with fixed coins make the requests of `coinStep`. -/ -theorem run_interpret_foldlM_pure (t : ℕ) (r : List Bool) (cfg : FiniteConfig k Bool Control Unit) +private theorem run_interpret_foldlM_pure (t : ℕ) (r : List Bool) + (cfg : FiniteConfig k Bool Control Unit) (s : S) : (OracleComp.interpret (handler oracle) (r.foldlM (fun cfg b => M.finiteStep (fun choices => choices <$> pure b) @@ -118,7 +120,7 @@ theorem run_interpret_foldlM_pure (t : ℕ) (r : List Bool) (cfg : FiniteConfig run_interpret_finiteStep_pure, ih] /-- An instruction drawing a fair coin averages the instructions with fixed coins. -/ -theorem run_interpret_finiteStep_sample +private theorem run_interpret_finiteStep_sample (query : Unit → List Bool → ProbOracleComp (fun _ : Unit × List Bool => List Bool) (List Bool)) (cfg : FiniteConfig k Bool Control Unit) (s : S) : @@ -139,7 +141,7 @@ theorem run_interpret_finiteStep_sample rfl /-- A clocked loop drawing fair coins averages the loops with fixed coins. -/ -theorem run_interpret_iterate_eq_coins +private theorem run_interpret_iterate_eq_coins (query : Unit → List Bool → ProbOracleComp (fun _ : Unit × List Bool => List Bool) (List Bool)) (n : ℕ) (cfg : FiniteConfig k Bool Control Unit) (s : S) : @@ -241,7 +243,7 @@ def simulate (t : ℕ) (x r : List Bool) (h : History) : (.ok (FiniteConfig.init M.initial x, h)) /-- The replay of an instruction is `replayStep`. -/ -theorem replay_coinStep (t : ℕ) (cfg : FiniteConfig k Bool Control Unit) (b : Bool) +private theorem replay_coinStep (t : ℕ) (cfg : FiniteConfig k Bool Control Unit) (b : Bool) (h : History) : (replay (coinStep M t cfg b)).run h = replayStep M t (cfg, h) b := by unfold coinStep MultiTapeMachine.finiteStep replayStep @@ -264,7 +266,7 @@ theorem replay_coinStep (t : ℕ) (cfg : FiniteConfig k Bool Control Unit) (b : split_ifs with hm <;> simp [hm] /-- A fold in the state and exception monad is a fold of results. -/ -theorem foldlM_run {σ ε β γ : Type} (g : β → γ → StateT σ (Except ε) β) (l : List γ) +private theorem foldlM_run {σ ε β γ : Type} (g : β → γ → StateT σ (Except ε) β) (l : List γ) (b : β) (s : σ) : (l.foldlM g b).run s = l.foldl (fun acc c => acc.bind fun p => (g p.1 c).run p.2) (.ok (b, s)) := by @@ -289,7 +291,7 @@ theorem foldlM_run {σ ε β γ : Type} (g : β → γ → StateT σ (Except ε) exact ih p.1 p.2 /-- A replay of a fold is a fold of replays. -/ -theorem replay_foldlM {β γ : Type} (f : β → γ → WordQueryComp Unit β) (l : List γ) +private theorem replay_foldlM {β γ : Type} (f : β → γ → WordQueryComp Unit β) (l : List γ) (b : β) : replay (l.foldlM f b) = l.foldlM (fun b c => replay (f b c)) b := (PFunctor.FreeM.isMonadHom_liftM (P := ⟨Unit × List Bool, fun _ => List Bool⟩) @@ -320,7 +322,7 @@ def ReplayInv (t : ℕ) (x : List Bool) (h : History) (i : ℕ) : | .error none => True /-- An instruction of the replay preserves the invariant. -/ -theorem replayInv_step {t : ℕ} {x : List Bool} {h : History} {i : ℕ} +private theorem replayInv_step {t : ℕ} {x : List Bool} {h : History} {i : ℕ} {acc : Except (Option (List Bool)) (FiniteConfig k Bool Control Unit × History)} (hacc : ReplayInv t x h i acc) (b : Bool) : ReplayInv t x h (i + 1) (acc.bind fun p => replayStep M t p b) := by @@ -356,7 +358,7 @@ theorem replayInv_step {t : ℕ} {x : List Bool} {h : History} {i : ℕ} · trivial /-- The replay satisfies the invariant after all its coins. -/ -theorem replayInv_simulate (t : ℕ) (x : List Bool) (h : History) (r : List Bool) : +private theorem replayInv_simulate (t : ℕ) (x : List Bool) (h : History) (r : List Bool) : ReplayInv t x h r.length (simulate M t x r h) := by suffices ∀ (l : List Bool) (acc) (i : ℕ), ReplayInv t x h i acc → ReplayInv t x h (i + l.length) @@ -371,10 +373,10 @@ theorem replayInv_simulate (t : ℕ) (x : List Bool) (h : History) (r : List Boo simpa [Nat.add_assoc, Nat.add_comm 1] using ih _ _ (replayInv_step M hacc b) /-- Truncate every reply of a history to its first `t` bits. -/ -def truncate (t : ℕ) (h : History) : History := h.map fun e => (e.1, e.2.take t) +private def truncate (t : ℕ) (h : History) : History := h.map fun e => (e.1, e.2.take t) /-- An instruction of the replay reads replies only through their first `t` bits. -/ -theorem replayStep_truncate (t : ℕ) (cfg : FiniteConfig k Bool Control Unit) (h : History) +private theorem replayStep_truncate (t : ℕ) (cfg : FiniteConfig k Bool Control Unit) (h : History) (b : Bool) : (replayStep M t (cfg, h) b).map (fun p => (p.1, truncate t p.2)) = (replayStep M t (cfg, truncate t h) b).map (fun p => (p.1, truncate t p.2)) := by @@ -396,7 +398,7 @@ theorem replayStep_truncate (t : ℕ) (cfg : FiniteConfig k Bool Control Unit) ( split_ifs <;> simp [Except.map, List.map_map, Function.comp_def, List.take_take] /-- The replay reads replies only through their first `t` bits. -/ -theorem simulate_truncate (t : ℕ) (x r : List Bool) {h h' : History} +private theorem simulate_truncate (t : ℕ) (x r : List Bool) {h h' : History} (hh : truncate t h = truncate t h') : (simulate M t x r h).map (fun p => (p.1, truncate t p.2)) = (simulate M t x r h').map (fun p => (p.1, truncate t p.2)) := by diff --git a/Complexity/Computability/Complexity/Classes/IP/GameTree.lean b/Complexity/Computability/Complexity/Classes/IP/GameTree.lean index c639e5614..c9cde759b 100644 --- a/Complexity/Computability/Complexity/Classes/IP/GameTree.lean +++ b/Complexity/Computability/Complexity/Classes/IP/GameTree.lean @@ -131,7 +131,8 @@ private theorem min_cap_add (a b : ℕ) : min cap (min cap a + b) = min cap (a + lia /-- A value returned into the empty stack is a fixed point. -/ -theorem step_nil_some (v : ℕ) : step D cap first next last leaf ([], some v) = ([], some v) := rfl +private theorem step_nil_some (v : ℕ) : step D cap first next last leaf ([], some v) = + ([], some v) := rfl section Correctness @@ -258,7 +259,7 @@ structure Good (P : X → Prop) (state : List (Frame X) × Option ℕ) : Prop wh value : ∀ v ∈ state.2, v ≤ cap /-- A step preserves the invariant. -/ -theorem Good.step {P : X → Prop} (hfirst : P first) (hnext : ∀ x, P x → P (next x)) +private theorem Good.step {P : X → Prop} (hfirst : P first) (hnext : ∀ x, P x → P (next x)) {state : List (Frame X) × Option ℕ} (h : Good D cap P state) : Good D cap P (step D cap first next last leaf state) := by obtain ⟨st, _ | v⟩ := state diff --git a/Complexity/Computability/Complexity/Classes/IP/GraphNonIsomorphism.lean b/Complexity/Computability/Complexity/Classes/IP/GraphNonIsomorphism.lean index b9bcfdbfd..8259e7e28 100644 --- a/Complexity/Computability/Complexity/Classes/IP/GraphNonIsomorphism.lean +++ b/Complexity/Computability/Complexity/Classes/IP/GraphNonIsomorphism.lean @@ -95,7 +95,8 @@ theorem keyRank_lt (k : Fin n → ℕ) (i : Fin n) : keyRank k i < n := by simp _ = n := by simp -theorem keyRank_lt_keyRank (k : Fin n → ℕ) {i j : Fin n} (h : k i < k j ∨ (k i = k j ∧ i < j)) : +private theorem keyRank_lt_keyRank (k : Fin n → ℕ) {i j : Fin n} + (h : k i < k j ∨ (k i = k j ∧ i < j)) : keyRank k i < keyRank k j := by unfold keyRank apply Finset.card_lt_card @@ -123,7 +124,7 @@ noncomputable def rankPerm (k : Fin n → ℕ) : Equiv.Perm (Fin n) := rfl /-- With distinct keys, permuting the positions permutes the ranks. -/ -theorem keyRank_comp {k : Fin n → ℕ} (hk : Function.Injective k) (σ : Equiv.Perm (Fin n)) +private theorem keyRank_comp {k : Fin n → ℕ} (hk : Function.Injective k) (σ : Equiv.Perm (Fin n)) (i : Fin n) : keyRank (k ∘ σ) i = keyRank k (σ i) := by have hsimp (k : Fin n → ℕ) (hk : Function.Injective k) (i : Fin n) : keyRank k i = (Finset.univ.filter fun j => k j < k i).card := by @@ -141,7 +142,7 @@ theorem keyRank_comp {k : Fin n → ℕ} (hk : Function.Injective k) (σ : Equiv intro j hj exact ⟨σ.symm j, by simpa using hj, by simp⟩ -theorem rankPerm_comp {k : Fin n → ℕ} (hk : Function.Injective k) (σ : Equiv.Perm (Fin n)) : +private theorem rankPerm_comp {k : Fin n → ℕ} (hk : Function.Injective k) (σ : Equiv.Perm (Fin n)) : rankPerm (k ∘ σ) = σ.trans (rankPerm k) := by ext i simp [keyRank_comp hk] @@ -153,7 +154,7 @@ noncomputable def relabelFin (A : Fin n → Fin n → Bool) (k : Fin n → ℕ) List.ofFn fun t : Fin (n * n) => A ((rankPerm k).symm (finProdFinEquiv.symm t).1) ((rankPerm k).symm (finProdFinEquiv.symm t).2) -theorem relabelFin_eq_flatten (A : Fin n → Fin n → Bool) (k : Fin n → ℕ) : +private theorem relabelFin_eq_flatten (A : Fin n → Fin n → Bool) (k : Fin n → ℕ) : relabelFin A k = (List.ofFn fun r : Fin n => List.ofFn fun s : Fin n => A ((rankPerm k).symm r) ((rankPerm k).symm s)).flatten := by rw [relabelFin, List.ofFn_mul] @@ -193,7 +194,7 @@ theorem exists_equiv_of_relabelFin_eq {n' : ℕ} {A : Fin n → Fin n → Bool} /-! ### Computing relabelings -/ /-- The key of position `i` below `n`; missing entries read as `0`. -/ -def keyAt (n : ℕ) (keys : List ℕ) (i : Fin n) : ℕ := keys.getD i 0 +private def keyAt (n : ℕ) (keys : List ℕ) (i : Fin n) : ℕ := keys.getD i 0 /-- The rank of position `i` among the positions below `n`, ordered by the entries of `keys` (missing entries read as `0`), ties broken by position. -/ @@ -211,12 +212,12 @@ def relabel (G : Graph) (keys : List ℕ) : List Bool := (orderOf G.distinctVertices.length keys).flatMap fun u => (orderOf G.distinctVertices.length keys).map fun v => G.adjIndex u v -theorem rankOf_eq (n : ℕ) (keys : List ℕ) (i : Fin n) : +private theorem rankOf_eq (n : ℕ) (keys : List ℕ) (i : Fin n) : rankOf n keys i = keyRank (keyAt n keys) i := by rw [rankOf, List.countP_range_eq_card_filter, keyRank] congr 1 -theorem filter_rankOf_eq (n : ℕ) (keys : List ℕ) (r : Fin n) : +private theorem filter_rankOf_eq (n : ℕ) (keys : List ℕ) (r : Fin n) : (List.range n).filter (fun i => decide (rankOf n keys i = r)) = [((rankPerm (keyAt n keys)).symm r : ℕ)] := by rw [List.filter_congr (q := fun i => decide (i = ((rankPerm (keyAt n keys)).symm r : ℕ))), @@ -227,7 +228,7 @@ theorem filter_rankOf_eq (n : ℕ) (keys : List ℕ) (r : Fin n) : rw [rankOf_eq n keys ⟨i, hi⟩, ← rankPerm_apply, decide_eq_decide] rw [← Fin.ext_iff, ← Equiv.eq_symm_apply, Fin.ext_iff] -theorem orderOf_eq (n : ℕ) (keys : List ℕ) : +private theorem orderOf_eq (n : ℕ) (keys : List ℕ) : orderOf n keys = List.ofFn fun r : Fin n => ((rankPerm (keyAt n keys)).symm r : ℕ) := by apply List.ext_getElem (by simp [orderOf]) intro r h1 h2 @@ -238,9 +239,9 @@ theorem orderOf_eq (n : ℕ) (keys : List ℕ) : rfl /-- The adjacency matrix of `G` on the positions of its distinct vertices. -/ -def adjFin (G : Graph) (i j : Fin G.distinctVertices.length) : Bool := G.adjIndex i j +private def adjFin (G : Graph) (i j : Fin G.distinctVertices.length) : Bool := G.adjIndex i j -theorem relabel_eq (G : Graph) (keys : List ℕ) : +private theorem relabel_eq (G : Graph) (keys : List ℕ) : relabel G keys = relabelFin (adjFin G) (keyAt G.distinctVertices.length keys) := by rw [relabel, orderOf_eq, relabelFin_eq_flatten, List.flatMap_def, List.map_ofFn] congr 1 @@ -311,7 +312,7 @@ noncomputable def relabelMessage (G : Graph) : ProbComp (List Bool) := noncomputable def relabelDist (n : ℕ) (A : Fin n → Fin n → Bool) : PMF (List Bool) := (PMF.uniformOfFintype (Fin n → BitString (keyWidth n))).map fun R => relabelFin A (keyValue ∘ R) -theorem eval_relabelMessage (G : Graph) : +private theorem eval_relabelMessage (G : Graph) : ProbComp.eval (relabelMessage G) = relabelDist G.distinctVertices.length (adjFin G) := by set n := G.distinctVertices.length rw [relabelMessage, ProbComp.eval_map, BitString.eval_sampleList, @@ -380,7 +381,7 @@ private theorem card_filter_not_injective_mul_le (n : ℕ) (β : Type*) [Fintype open Classical in /-- Random keys collide with probability at most `1 / 16`. -/ -theorem card_filter_not_injective_div_le (n : ℕ) : +private theorem card_filter_not_injective_div_le (n : ℕ) : ((Finset.univ.filter fun R : Fin n → BitString (keyWidth n) => ¬ Function.Injective R).card : ENNReal) / Fintype.card (Fin n → BitString (keyWidth n)) ≤ 1 / 16 := by @@ -465,7 +466,7 @@ theorem tsum_relabelDist_le {n n' : ℕ} {A : Fin n → Fin n → Bool} {A' : Fi · exact add_le_add le_rfl (card_filter_not_injective_div_le n) /-- Equal relabelings come from isomorphic adjacency matrices. -/ -theorem exists_equiv_of_mem_support_relabelDist {n n' : ℕ} {A : Fin n → Fin n → Bool} +private theorem exists_equiv_of_mem_support_relabelDist {n n' : ℕ} {A : Fin n → Fin n → Bool} {A' : Fin n' → Fin n' → Bool} {m : List Bool} (hm : m ∈ (relabelDist n A).support) (hm' : m ∈ (relabelDist n' A').support) : ∃ σ : Fin n ≃ Fin n', ∀ i j, A' (σ i) (σ j) = A i j := by @@ -492,7 +493,7 @@ noncomputable def verifier (x : Graph × Graph) : WordOracleComp Unit Bool := /-- The honest prover: name the graph of which the message is a possible relabeling. -/ noncomputable def prover (x : Graph × Graph) : Prover Unit := guessingProver (message x) -theorem eval_message (x : Graph × Graph) (b : Bool) : ProbComp.eval (message x b) = +private theorem eval_message (x : Graph × Graph) (b : Bool) : ProbComp.eval (message x b) = relabelDist (if b then x.2 else x.1).distinctVertices.length (adjFin (if b then x.2 else x.1)) := eval_relabelMessage _ @@ -513,7 +514,7 @@ theorem acceptProb_round_le {x : Graph × Graph} (hx : x ∈ GraphIsomorphism) ( /-- **Completeness of one round.** On non-isomorphic graphs the honest prover always names the picked graph. -/ -theorem acceptProb_round_prover {x : Graph × Graph} (hx : x ∈ GraphNonIsomorphism) : +private theorem acceptProb_round_prover {x : Graph × Graph} (hx : x ∈ GraphNonIsomorphism) : acceptProb (round x) (prover x) = 1 := by refine acceptProb_guessingProver fun m hm hm' => hx ?_ simp only [eval_message] at hm hm' @@ -543,7 +544,7 @@ theorem isInteractiveProof_verifier : sound _ hx := acceptProb_verifier_le (not_not.1 hx) /-- Relabeling a computed graph by random keys is strict PPT. -/ -theorem isPPTOn_relabelMessage {γ : Type} {input : γ ↪ List Bool} {G : γ → Graph} +private theorem isPPTOn_relabelMessage {γ : Type} {input : γ ↪ List Bool} {G : γ → Graph} (hG : ComputableTidilyInPolyTime G input encGraph) : IsPPTOn input encBits (fun x => relabelMessage (G x)) := by have hn : ComputableTidilyInPolyTime (fun x => (G x).distinctVertices.length) input encUnary := diff --git a/Complexity/Computability/Complexity/Classes/IP/Repetition.lean b/Complexity/Computability/Complexity/Classes/IP/Repetition.lean index 853602404..41a0d7283 100644 --- a/Complexity/Computability/Complexity/Classes/IP/Repetition.lean +++ b/Complexity/Computability/Complexity/Classes/IP/Repetition.lean @@ -59,7 +59,8 @@ def sequentialRepeat : ℕ → WordOracleComp Operation Bool → WordOracleComp /-- Running `rest` after an accepting run of `round` is accepted with the probability of `rest` from each final prover state of an accepting run, averaged over those states. -/ -theorem acceptProb_bind_ite (P : Prover Operation) (round rest : WordOracleComp Operation Bool) : +private theorem acceptProb_bind_ite (P : Prover Operation) + (round rest : WordOracleComp Operation Bool) : acceptProb (do let ok ← round; if ok then rest else pure false) P = ∑' s, P.run round P.init (true, s) * acceptProb rest { P with init := s } := by simp only [acceptProb, Prover.run_bind, PMF.map_bind] diff --git a/Complexity/Computability/Complexity/Classes/IP/Simulation.lean b/Complexity/Computability/Complexity/Classes/IP/Simulation.lean index 758f21560..c30206ed8 100644 --- a/Complexity/Computability/Complexity/Classes/IP/Simulation.lean +++ b/Complexity/Computability/Complexity/Classes/IP/Simulation.lean @@ -155,7 +155,7 @@ theorem accepts_eq_true_iff (x r : List Bool) (h : History) : cases rest <;> simp [Except.map, replayOutcome] /-- `accepts_eq_true_iff` for any number of coins equal to the length of the coins. -/ -theorem accepts_eq_true_iff_of_length {x r : List Bool} {t : ℕ} (hr : r.length = t) +private theorem accepts_eq_true_iff_of_length {x r : List Bool} {t : ℕ} (hr : r.length = t) (h : History) : accepts M x r h = true ↔ outcome (coinProgram M t x r) h = .done true := by subst hr exact accepts_eq_true_iff M x r h @@ -167,14 +167,14 @@ section PolyTime open ComputableTidilyInPolyTime /-- The instruction of `M` in the configuration `cfg` with the coin `b`, unless it has halted. -/ -def instruction (cfg : MultiTapeMachine.FiniteConfig k Bool Control Unit) (b : Bool) : +private def instruction (cfg : MultiTapeMachine.FiniteConfig k Bool Control Unit) (b : Bool) : Option (MultiTapeMachine.Action k Bool Control Unit) := cfg.tapes.state.map fun c => M.tr c cfg.tapes.inputSymbol cfg.tapes.workTapeSymbols cfg.answerSymbols b /-- Answer a request on the channel `op` from the history, moving to the control state `next`, or stop when the history is exhausted or sends another message. -/ -def answerFromHistory (t : ℕ) (op : Unit) (next : Control) (s : AliveState k Control) : +private def answerFromHistory (t : ℕ) (op : Unit) (next : Control) (s : AliveState k Control) : AliveState k Control := if s.2.1.isEmpty then (s.1, s.2.1, false) else if (s.2.1.headD ([], [])).1 = (s.1.channels op).1 then @@ -182,7 +182,7 @@ def answerFromHistory (t : ℕ) (op : Unit) (next : Control) (s : AliveState k C else (s.1, s.2.1, false) /-- The live replay step by its liveness and instruction. -/ -def taggedStep (t : ℕ) : +private def taggedStep (t : ℕ) : Bool × Option (MultiTapeMachine.Action k Bool Control Unit) → AliveState k Control → AliveState k Control | (false, _), s => s @@ -191,7 +191,7 @@ def taggedStep (t : ℕ) : | (true, some (.query op next)), s => answerFromHistory t op next s /-- The live replay step as a case distinction on a finite tag. -/ -theorem aliveStep_eq (t : ℕ) (s : AliveState k Control) (b : Bool) : +private theorem aliveStep_eq (t : ℕ) (s : AliveState k Control) (b : Bool) : aliveStep M t s b = taggedStep t (s.2.2, instruction M s.1 b) s := by obtain ⟨cfg, rest, _ | _⟩ := s · rfl @@ -215,11 +215,11 @@ theorem aliveStep_eq (t : ℕ) (s : AliveState k Control) (b : Bool) : variable [Finite Control] /-- Live replay states, encoded by their fields. -/ -noncomputable abbrev encAliveState : AliveState k Control ↪ List Bool := +private noncomputable abbrev encAliveState : AliveState k Control ↪ List Bool := encPair encFiniteConfig (encPair encHistory encBool) /-- The instruction is polynomial-time: it reads finitely many observations. -/ -theorem computableTidilyInPolyTime_instruction : +private theorem computableTidilyInPolyTime_instruction : ComputableTidilyInPolyTime (fun p : MultiTapeMachine.FiniteConfig k Bool Control Unit × Bool => instruction M p.1 p.2) (encPair encFiniteConfig encBool) (encFinite (Option (MultiTapeMachine.Action k Bool Control Unit))) := by @@ -236,7 +236,7 @@ theorem computableTidilyInPolyTime_instruction : M.tr c obs.2.1 obs.2.2.1 obs.2.2.2.1 obs.2.2.2.2).comp hobs).of_enc_eq fun _ => rfl /-- Answering from the history is polynomial-time. -/ -theorem computableTidilyInPolyTime_answerFromHistory (op : Unit) (next : Control) : +private theorem computableTidilyInPolyTime_answerFromHistory (op : Unit) (next : Control) : ComputableTidilyInPolyTime (fun p : (ℕ × AliveState k Control) × Bool => answerFromHistory p.1.1 op next p.1.2) (encPair (encPair encUnary encAliveState) encBool) encAliveState := by @@ -244,7 +244,7 @@ theorem computableTidilyInPolyTime_answerFromHistory (op : Unit) (next : Control fun_prop /-- **A step of the live replay is polynomial-time.** -/ -theorem computableTidilyInPolyTime_aliveStep : +private theorem computableTidilyInPolyTime_aliveStep : ComputableTidilyInPolyTime (fun p : (ℕ × AliveState k Control) × Bool => aliveStep M p.1.1 p.1.2 p.2) (encPair (encPair encUnary encAliveState) encBool) encAliveState := by @@ -267,7 +267,7 @@ theorem computableTidilyInPolyTime_aliveStep : omit [Finite Control] in /-- A step of the live replay grows the storage by a bounded amount and consumes the history. -/ -theorem aliveStep_spaceBound {n i t : ℕ} {h : History} {s : AliveState k Control} +private theorem aliveStep_spaceBound {n i t : ℕ} {h : History} {s : AliveState k Control} (hs : MultiTapeMachine.FiniteConfig.SpaceBound n i t s.1 ∧ s.2.1 <:+ h) (b : Bool) : MultiTapeMachine.FiniteConfig.SpaceBound n (i + 1) t (aliveStep M t s b).1 ∧ (aliveStep M t s b).2.1 <:+ h := by @@ -294,7 +294,7 @@ theorem aliveStep_spaceBound {n i t : ℕ} {h : History} {s : AliveState k Contr · exact ⟨hspace.mono le_rfl (by lia) le_rfl, hsuffix⟩ /-- **The live replay is polynomial-time** in the input, the coins and the history. -/ -theorem computableTidilyInPolyTime_aliveRun : +private theorem computableTidilyInPolyTime_aliveRun : ComputableTidilyInPolyTime (fun p : List Bool × List Bool × History => aliveRun M p.1 p.2.1 p.2.2) (encPair encBits (encPair encBits encHistory)) encAliveState := by @@ -352,7 +352,7 @@ def countAccepts (q : α × History) : ℕ := open Classical in /-- After `j` rounds the count has tried the first `j` values of the counter. -/ -theorem iterate_countStep (q : α × History) (m j : ℕ) : +private theorem iterate_countStep (q : α × History) (m j : ℕ) : (countStep M enc)^[j] (q, List.replicate m false, 0) = (q, increment^[j] (List.replicate m false), ((Finset.range j).filter fun i => diff --git a/Complexity/Computability/Complexity/Classes/IP/TQBF/Tokens.lean b/Complexity/Computability/Complexity/Classes/IP/TQBF/Tokens.lean index 779acda35..c7bd001c9 100644 --- a/Complexity/Computability/Complexity/Classes/IP/TQBF/Tokens.lean +++ b/Complexity/Computability/Complexity/Classes/IP/TQBF/Tokens.lean @@ -137,7 +137,7 @@ theorem tokens_append_inj {e e' : ArithQBF ℕ} {r r' : List (Kind × ℕ)} exact ⟨rfl, rfl⟩ /-- Linearizations come first in prefix order. -/ -theorem tokens_lins (xs : List ℕ) (e : ArithQBF ℕ) : +private theorem tokens_lins (xs : List ℕ) (e : ArithQBF ℕ) : (lins xs e).tokens = xs.map (fun x => (Kind.lin, x)) ++ e.tokens := by induction xs with | nil => rfl diff --git a/Complexity/Computability/Complexity/Classes/IP/TQBF/Words.lean b/Complexity/Computability/Complexity/Classes/IP/TQBF/Words.lean index 2f64cb268..ade0c5d9c 100644 --- a/Complexity/Computability/Complexity/Classes/IP/TQBF/Words.lean +++ b/Complexity/Computability/Complexity/Classes/IP/TQBF/Words.lean @@ -224,7 +224,7 @@ theorem lt_of_mem_decodeReply [NeZero p] {D : ℕ} {word : List Bool} {a : ℕ} obtain ⟨row, -, rfl⟩ := List.mem_map.1 ha exact Nat.mod_lt _ (NeZero.pos p) -theorem lt_two_pow_width {a : ℕ} (hp : a < p) : a < 2 ^ width p := +private theorem lt_two_pow_width {a : ℕ} (hp : a < p) : a < 2 ^ width p := hp.trans (Nat.lt_pow_succ_log_self (by norm_num) p) /-- The rows of the honest encoding of `l` are the bits of its elements. -/ diff --git a/Complexity/Computability/Complexity/Classes/Ladner.lean b/Complexity/Computability/Complexity/Classes/Ladner.lean index bc740d8be..1521edaf6 100644 --- a/Complexity/Computability/Complexity/Classes/Ladner.lean +++ b/Complexity/Computability/Complexity/Classes/Ladner.lean @@ -119,7 +119,7 @@ theorem universal_desc_of_halted {k : ℕ} {State : Type} [Fintype State] (eS : rfl /-- Every description is the description of machines with arbitrarily large indices. -/ -theorem exists_index_ge (d : Desc) (B : ℕ) : +private theorem exists_index_ge (d : Desc) (B : ℕ) : ∃ i, B ≤ i ∧ decodeDesc (unframe (word i)) = d := by refine ⟨index (frame (eDesc d) ++ List.replicate B false), ?_, by rw [word_index, decodeDesc_unframe_frame_append]⟩ @@ -131,7 +131,7 @@ theorem exists_index_ge (d : Desc) (B : ℕ) : /-- From some point on, the clock of the machine with index `i` on the words with indices below `n` is at most `n`. -/ -theorem eventually_clock_le (i : ℕ) : +private theorem eventually_clock_le (i : ℕ) : ∀ᶠ n in Filter.atTop, ∀ j < n, clock i (word j).length ≤ n := by have hpoly : PolynomiallyBounded fun l => (2 * l + 2) ^ i := by fun_prop obtain ⟨L, hL⟩ := Filter.eventually_atTop.mp (PolynomiallyBounded.eventually_lt_two_pow hpoly) @@ -178,7 +178,7 @@ of the encoded formula. -/ noncomputable def padBounded (C : ℕ) (φ : CNF ℕ) : List Bool := pad (encCNF φ) (capPow (encCNF φ).length (H (encCNF φ).length) (((encCNF φ).length + 1) ^ C)) -theorem computableTidilyInPolyTime_padBounded (C : ℕ) : +private theorem computableTidilyInPolyTime_padBounded (C : ℕ) : ComputableTidilyInPolyTime (padBounded C) encCNF encBits := by have henc : ComputableTidilyInPolyTime (fun φ => encCNF φ) encCNF encBits := ComputableTidilyInPolyTime.encode encCNF @@ -271,7 +271,7 @@ theorem shrink_mem_SAT_iff {R : CNF ℕ → List Bool} (hR : ∀ φ, φ ∈ SAT `c * (n + 1) ^ d` on formulas of length `n`, and let `H` exceed `d` from `M` on. If `R φ` padded a formula at least as long as `φ`, with `φ` of length at least `N`, its padding would be longer than `R φ`. -/ -theorem length_shrink_lt {R : CNF ℕ → List Bool} {c d M N : ℕ} +private theorem length_shrink_lt {R : CNF ℕ → List Bool} {c d M N : ℕ} (hRlen : ∀ φ, (R φ).length ≤ c * ((encCNF φ).length + 1) ^ d) (hM : ∀ m ≥ M, d + 1 ≤ H m) (hN₁ : (encCNF falseCNF).length < N) (hN₂ : M ≤ N) (hN₃ : c * 2 ^ d < N) {φ : CNF ℕ} (hφ : N ≤ (encCNF φ).length) : (encCNF (shrink R N φ)).length < (encCNF φ).length := by diff --git a/Complexity/Computability/Complexity/Classes/Ladner/Basic.lean b/Complexity/Computability/Complexity/Classes/Ladner/Basic.lean index ebb1ff687..700bea176 100644 --- a/Complexity/Computability/Complexity/Classes/Ladner/Basic.lean +++ b/Complexity/Computability/Complexity/Classes/Ladner/Basic.lean @@ -83,19 +83,19 @@ def word (j : ℕ) : List Bool := (j + 1).bits.dropLast `true`. -/ def index (w : List Bool) : ℕ := w.foldr Nat.bit 1 - 1 -theorem foldr_bit_one_ne_zero (w : List Bool) : w.foldr Nat.bit 1 ≠ 0 := by +private theorem foldr_bit_one_ne_zero (w : List Bool) : w.foldr Nat.bit 1 ≠ 0 := by induction w with | nil => simp | cons b w ih => exact Nat.bit_ne_zero b ih -theorem bits_foldr_bit_one (w : List Bool) : (w.foldr Nat.bit 1).bits = w ++ [true] := by +private theorem bits_foldr_bit_one (w : List Bool) : (w.foldr Nat.bit 1).bits = w ++ [true] := by induction w with | nil => simp | cons b w ih => rw [List.foldr_cons, Nat.bits_append_bit _ _ fun h => absurd h (foldr_bit_one_ne_zero w), ih, List.cons_append] -theorem foldr_bit_one_lt (w : List Bool) : w.foldr Nat.bit 1 < 2 ^ (w.length + 1) := by +private theorem foldr_bit_one_lt (w : List Bool) : w.foldr Nat.bit 1 < 2 ^ (w.length + 1) := by induction w with | nil => simp | cons b w ih => @@ -120,7 +120,7 @@ theorem two_pow_length_word_le (j : ℕ) : 2 ^ (word j).length ≤ j + 1 := by rw [word, List.length_dropLast, Nat.size_eq_bits_len] exact Nat.lt_size.mp (Nat.sub_lt (Nat.size_pos.mpr (Nat.succ_pos j)) Nat.one_pos) -theorem length_word_lt (j : ℕ) : (word j).length < j + 1 := +private theorem length_word_lt (j : ℕ) : (word j).length < j + 1 := (Nat.lt_two_pow_self).trans_le (two_pow_length_word_le j) /-! ### Padding -/ @@ -138,7 +138,7 @@ theorem length_pad (u : List Bool) (k : ℕ) : (pad u k).length = u.length + 1 + simp only [pad, List.length_append, List.length_cons, List.length_replicate] omega -theorem idxOf_false_replicate_append (k : ℕ) (l : List Bool) : +private theorem idxOf_false_replicate_append (k : ℕ) (l : List Bool) : (List.replicate k true ++ false :: l).idxOf false = k := by induction k with | zero => simp @@ -157,7 +157,7 @@ theorem pad_inj {u u' : List Bool} {k k' : ℕ} : pad u k = pad u' k' ↔ u = u' ⟨fun h => by simpa using congrArg unpad h, fun ⟨hu, hk⟩ => hu ▸ hk ▸ rfl⟩ /-- A word with a `false` is a run of `true`s up to its first `false`, and what follows. -/ -theorem eq_replicate_idxOf_false {l : List Bool} (hl : false ∈ l) : +private theorem eq_replicate_idxOf_false {l : List Bool} (hl : false ∈ l) : l = List.replicate (l.idxOf false) true ++ false :: l.drop (l.idxOf false + 1) := by induction l with | nil => simp at hl diff --git a/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder.lean b/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder.lean index 26c219ae5..85c617e99 100644 --- a/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder.lean +++ b/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder.lean @@ -116,7 +116,7 @@ def bitExpr (i : ℕ) {l : ℕ} (vars : Fin l → ℕ) : Expr := variable {v} -theorem eval_tupleExprWith {l n : ℕ} (values : Fin l → Expr) {regs : List ℕ} +private theorem eval_tupleExprWith {l n : ℕ} (values : Fin l → Expr) {regs : List ℕ} (h0 : regs.getD 0 0 = n) (x : Fin l → Fin n) (hx : ∀ m, (values m).eval regs = x m) : (tupleExprWith values).eval regs = tupleIndex x := by @@ -128,7 +128,7 @@ theorem eval_tupleExpr {l n : ℕ} (vars : Fin l → ℕ) {regs : List ℕ} (h0 (tupleExpr vars).eval regs = tupleIndex x := eval_tupleExprWith _ h0 x hx -theorem eval_startExpr {a : EncodedStructure} (ha : v.WellFormed a) {regs : List ℕ} +private theorem eval_startExpr {a : EncodedStructure} (ha : v.WellFormed a) {regs : List ℕ} (h0 : regs.getD 0 0 = a.1) {i : ℕ} (hi : i ≤ v.count) : (startExpr v i).eval regs = tableStart a i := by simp only [startExpr, eval_add, eval_mul, eval_const, eval_reg, h0, eval_sum, List.map_ofFn, @@ -156,7 +156,7 @@ theorem eval_bitExprWith {a : EncodedStructure} (ha : v.WellFormed a) {regs : Li simp only [bitExprWith, eval_add, eval_mul, eval_const, eval_startExpr ha h0 hi, eval_tupleExprWith values h0 x hx] -theorem eval_bitExpr {a : EncodedStructure} (ha : v.WellFormed a) {regs : List ℕ} +private theorem eval_bitExpr {a : EncodedStructure} (ha : v.WellFormed a) {regs : List ℕ} (h0 : regs.getD 0 0 = a.1) {i : ℕ} (hi : i ≤ v.count) {l : ℕ} (vars : Fin l → ℕ) (x : Fin l → Fin a.1) (hx : ∀ m, regs.getD (vars m) 0 = x m) : (bitExpr v i vars).eval regs = tableStart a i + 2 * tupleIndex x + 1 := @@ -193,9 +193,9 @@ def shapeCode (b T F : ℕ) : List Instr := (List.range v.count).flatMap (fun i => tableCode v (b + 3 + 6 * i) i F) ++ [.read (reg 1) F F T] -theorem length_tableCode (c i F : ℕ) : (tableCode v c i F).length = 6 := rfl +private theorem length_tableCode (c i F : ℕ) : (tableCode v c i F).length = 6 := rfl -theorem length_tables (b F : ℕ) : +private theorem length_tables (b F : ℕ) : ((List.range v.count).flatMap fun i => tableCode v (b + 3 + 6 * i) i F).length = 6 * v.count := by rw [List.length_flatMap] @@ -215,7 +215,7 @@ instance (a : EncodedStructure) (i : ℕ) : Decidable (TableOk v a i) := variable {v} -theorem wellFormed_iff_tableOk {a : EncodedStructure} : +private theorem wellFormed_iff_tableOk {a : EncodedStructure} : v.WellFormed a ↔ (∀ i < v.count, TableOk v a i) ∧ a.2.length = v.count := by constructor · rintro ⟨hlen, htab⟩ @@ -232,12 +232,12 @@ theorem wellFormed_iff_tableOk {a : EncodedStructure} : variable {P : CounterProgram} {a : EncodedStructure} {B : ℕ} -theorem eval_lenExpr {regs : List ℕ} (h0 : regs.getD 0 0 = a.1) (i : ℕ) : +private theorem eval_lenExpr {regs : List ℕ} (h0 : regs.getD 0 0 = a.1) (i : ℕ) : (lenExpr v i).eval regs = a.1 ^ arityAt v i := by simp only [lenExpr, eval_pow, eval_reg, h0] /-- Counting the markers of the unary cardinality. -/ -theorem reaches_count {b F : ℕ} +private theorem reaches_count {b F : ℕ} (h₀ : P.instr b = .read (mul (const 2) (reg 0)) (b + 1) (b + 2) F) (h₁ : P.instr (b + 1) = .assign 0 (add (reg 0) (const 1)) b) (hnB : a.1 ≤ B) : ∀ e (regs : List ℕ), a.1 - regs.getD 0 0 = e → regs.getD 0 0 ≤ a.1 → 0 < regs.length → @@ -265,7 +265,7 @@ theorem reaches_count {b F : ℕ} exact Reaches.assign h₁ hB (by simpa using hreach) /-- The markers of a table, counted up to `n ^ k`. -/ -theorem reaches_markers {c i F : ℕ} (hP : P.CodeAt c (tableCode v c i F)) +private theorem reaches_markers {c i F : ℕ} (hP : P.CodeAt c (tableCode v c i F)) (hi : i < a.2.length) (hLB : a.1 ^ arityAt v i ≤ B) : ∀ e j (regs : List ℕ), a.1 ^ arityAt v i - j = e → j ≤ a.1 ^ arityAt v i → j ≤ a.2[i].length → regs.getD 0 0 = a.1 → regs.getD 1 0 = tableStart a i → @@ -320,7 +320,7 @@ theorem reaches_markers {c i F : ℕ} (hP : P.CodeAt c (tableCode v c i F)) cardinality in register `0` and the position of the table in register `1`, the program moves register `1` past the table and goes to `c + 6` if the table exists and has `n ^ k` bits, and goes to `F` otherwise. -/ -theorem reaches_tableCode {c i F : ℕ} (hP : P.CodeAt c (tableCode v c i F)) +private theorem reaches_tableCode {c i F : ℕ} (hP : P.CodeAt c (tableCode v c i F)) (hi : i ≤ a.2.length) (hLB : a.1 ^ arityAt v i ≤ B) (hwB : (encStructure a).length ≤ B) (regs : List ℕ) (h0 : regs.getD 0 0 = a.1) (h1 : regs.getD 1 0 = tableStart a i) (hlen : 3 ≤ regs.length) (hB : ∀ r ∈ regs, r ≤ B) : @@ -401,7 +401,7 @@ theorem reaches_tableCode {c i F : ℕ} (hP : P.CodeAt c (tableCode v c i F)) exact Reaches.refl _ /-- **Checking the tables**, from the table at position `m` on. -/ -theorem reaches_tables {b F : ℕ} +private theorem reaches_tables {b F : ℕ} (hP : P.CodeAt (b + 3) ((List.range v.count).flatMap fun i => tableCode v (b + 3 + 6 * i) i F)) (hLB : ∀ i, a.1 ^ arityAt v i ≤ B) (hwB : (encStructure a).length ≤ B) : ∀ e m (regs : List ℕ), v.count - m = e → m ≤ v.count → (∀ i < m, TableOk v a i) → @@ -550,7 +550,7 @@ def termReg {α : Type*} (fv : α → ℕ) (base : ℕ) {k : ℕ} Sum.elim fv (fun i : Fin k => base + i) (termVar t) /-- The register of the variable of a term holds the value of the term. -/ -theorem getD_termReg {α : Type*} {n : ℕ} [L.Structure (Fin n)] {fv : α → ℕ} +private theorem getD_termReg {α : Type*} {n : ℕ} [L.Structure (Fin n)] {fv : α → ℕ} {base k : ℕ} {regs : List ℕ} {val : α → Fin n} {xs : Fin k → Fin n} (hv : ∀ x, regs.getD (fv x) 0 = val x) (hxs : ∀ i : Fin k, regs.getD (base + i) 0 = xs i) (t : L.Term (α ⊕ Fin k)) : @@ -575,7 +575,7 @@ def formulaCode {α : Type*} (fv : α → ℕ) (base : ℕ) {k : ℕ} (φ : L.BoundedFormula α k) (b T F : ℕ) : List Instr := formulaCodeWith (atomicCompiler v fv base) base φ b T F -theorem length_formulaCode {α : Type*} (fv : α → ℕ) (base : ℕ) {k : ℕ} +private theorem length_formulaCode {α : Type*} (fv : α → ℕ) (base : ℕ) {k : ℕ} (φ : L.BoundedFormula α k) (b T F : ℕ) : (formulaCode v fv base φ b T F).length = codeLength φ := length_formulaCodeWith _ _ _ _ _ _ diff --git a/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder/Formula.lean b/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder/Formula.lean index 6f5b3afe8..ed6205cc2 100644 --- a/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder/Formula.lean +++ b/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder/Formula.lean @@ -59,7 +59,7 @@ def boundDepth {α : Type*} : ∀ {k : ℕ}, L.BoundedFormula α k → ℕ | _, .imp φ ψ => max (boundDepth φ) (boundDepth ψ) | _, .all φ => boundDepth φ -theorem le_boundDepth {α : Type*} : ∀ {k : ℕ} (φ : L.BoundedFormula α k), k ≤ boundDepth φ +private theorem le_boundDepth {α : Type*} : ∀ {k : ℕ} (φ : L.BoundedFormula α k), k ≤ boundDepth φ | _, .falsum => le_rfl | _, .equal _ _ => le_rfl | _, .rel _ _ => le_rfl diff --git a/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder/Ordered.lean b/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder/Ordered.lean index 432c7171f..f26c6f1f2 100644 --- a/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder/Ordered.lean +++ b/Complexity/Computability/Complexity/Classes/LogSpace/FirstOrder/Ordered.lean @@ -100,7 +100,7 @@ def termExpr {α : Type*} (fv : α → ℕ) (base : ℕ) {k : ℕ} : variable {v} /-- Compiled terms realize genuine numeric constants as well as variables. -/ -theorem eval_termExpr {n : ℕ} [Fact (2 ≤ n)] [L.Structure (Fin n)] +private theorem eval_termExpr {n : ℕ} [Fact (2 ≤ n)] [L.Structure (Fin n)] {α : Type*} {fv : α → ℕ} {base k : ℕ} {regs : List ℕ} {val : α → Fin n} {xs : Fin k → Fin n} (h0 : regs.getD 0 0 = n) (hv : ∀ x, regs.getD (fv x) 0 = val x) @@ -191,7 +191,7 @@ def formulaCode {α : Type*} (fv : α → ℕ) (base : ℕ) {k : ℕ} (φ : (language L).BoundedFormula α k) (b T F : ℕ) : List Instr := formulaCodeWith (atomicCompiler v fv base) base φ b T F -theorem length_formulaCode {α : Type*} (fv : α → ℕ) (base : ℕ) {k : ℕ} +private theorem length_formulaCode {α : Type*} (fv : α → ℕ) (base : ℕ) {k : ℕ} (φ : (language L).BoundedFormula α k) (b T F : ℕ) : (formulaCode v fv base φ b T F).length = codeLength φ := length_formulaCodeWith _ _ _ _ _ _ @@ -199,7 +199,8 @@ theorem length_formulaCode {α : Type*} (fv : α → ℕ) (base : ℕ) {k : ℕ} variable {v} /-- Evaluation of every ordered formula, including genuine constants inside quantified atoms. -/ -theorem reaches_formulaCode {P : CounterProgram} {a : EncodedStructure} (ha : v.WellFormed a) +private theorem reaches_formulaCode {P : CounterProgram} {a : EncodedStructure} + (ha : v.WellFormed a) [Fact (2 ≤ a.1)] {B : ℕ} (hnB : a.1 ≤ B) {α : Type*} (fv : α → ℕ) (base : ℕ) (hbase : 0 < base) (hfv : ∀ x, fv x < base) (val : α → Fin a.1) : ∀ {k : ℕ} (φ : (language L).BoundedFormula α k) (b T F : ℕ) diff --git a/Complexity/Computability/Complexity/Classes/MIP/OptimalProver.lean b/Complexity/Computability/Complexity/Classes/MIP/OptimalProver.lean index bb811c9c1..f158a2e04 100644 --- a/Complexity/Computability/Complexity/Classes/MIP/OptimalProver.lean +++ b/Complexity/Computability/Complexity/Classes/MIP/OptimalProver.lean @@ -105,7 +105,8 @@ local notation "handler" o => ProbOracleComp.handler (fun n => StateT.lift (ProbComp.unifOracle n)) o /-- An instruction with a fixed coin makes the requests of `coinStep`. -/ -theorem run_interpret_finiteStep_pure (t : ℕ) (cfg : FiniteConfig k Bool Control Oracle) (b : Bool) +private theorem run_interpret_finiteStep_pure (t : ℕ) (cfg : FiniteConfig k Bool Control Oracle) + (b : Bool) (s : S) : (OracleComp.interpret (handler oracle) (M.finiteStep (fun choices => choices <$> pure b) (fun op w => List.take t <$> ProbOracleComp.query (op, w)) cfg)).run s = @@ -122,7 +123,8 @@ theorem run_interpret_finiteStep_pure (t : ℕ) (cfg : FiniteConfig k Bool Contr OracleComp.interpret_query, OracleComp.interpret_pure] /-- Instructions with fixed coins make the requests of `coinStep`. -/ -theorem run_interpret_foldlM_pure (t : ℕ) (r : List Bool) (cfg : FiniteConfig k Bool Control Oracle) +private theorem run_interpret_foldlM_pure (t : ℕ) (r : List Bool) + (cfg : FiniteConfig k Bool Control Oracle) (s : S) : (OracleComp.interpret (handler oracle) (r.foldlM (fun cfg b => M.finiteStep (fun choices => choices <$> pure b) @@ -135,7 +137,7 @@ theorem run_interpret_foldlM_pure (t : ℕ) (r : List Bool) (cfg : FiniteConfig run_interpret_finiteStep_pure, ih] /-- An instruction drawing a fair coin averages the instructions with fixed coins. -/ -theorem run_interpret_finiteStep_sample +private theorem run_interpret_finiteStep_sample (query : Oracle → List Bool → ProbOracleComp (fun _ : Oracle × List Bool => List Bool) (List Bool)) (cfg : FiniteConfig k Bool Control Oracle) (s : S) : @@ -156,7 +158,7 @@ theorem run_interpret_finiteStep_sample rfl /-- A clocked loop drawing fair coins averages the loops with fixed coins. -/ -theorem run_interpret_iterate_eq_coins +private theorem run_interpret_iterate_eq_coins (query : Oracle → List Bool → ProbOracleComp (fun _ : Oracle × List Bool => List Bool) (List Bool)) (n : ℕ) (cfg : FiniteConfig k Bool Control Oracle) (s : S) : @@ -179,7 +181,7 @@ theorem run_interpret_iterate_eq_coins exact PMF.bind_comm _ _ _ /-- **The multi-channel run averages the programs of fixed coins** against every stateful oracle. -/ -theorem run_interpret_runOracle_eq_coins (t : ℕ) (x : List Bool) (s : S) : +private theorem run_interpret_runOracle_eq_coins (t : ℕ) (x : List Bool) (s : S) : (OracleComp.interpret (handler oracle) (M.runOracle t x)).run s = (BitString.uniformList t).bind fun r => (OracleComp.interpret oracle ((fun cfg => cfg.tapes.output) <$> @@ -284,7 +286,7 @@ variable [DecidableEq Oracle] (M : MultiTapePTM k Bool Control Oracle) /-- Every configuration reachable by `coinStep M t cfg b` from a configuration with query buffers of length at most `i` has query buffers of length at most `i + 1`, and `coinStep M t cfg b` is a 1-query bounded program when `i ≤ t`. -/ -theorem isBoundedComp_coinStep_bind {t i n : ℕ} {cfg : FiniteConfig k Bool Control Oracle} +private theorem isBoundedComp_coinStep_bind {t i n : ℕ} {cfg : FiniteConfig k Bool Control Oracle} (hbuf : ∀ op, (cfg.channels op).1.length ≤ i) (hit : i ≤ t) (b : Bool) {cont : FiniteConfig k Bool Control Oracle → WordQueryComp Oracle α} (hcont : ∀ cfg', (∀ op, (cfg'.channels op).1.length ≤ i + 1) → IsBoundedComp t n (cont cfg')) : @@ -316,7 +318,7 @@ theorem isBoundedComp_coinStep_bind {t i n : ℕ} {cfg : FiniteConfig k Bool Con · simpa [FiniteConfig.receive, heq] using (hbuf op').trans (Nat.le_succ i) /-- Folding `coinStep M t` over a list of coins `r` produces a bounded query program. -/ -theorem isBoundedComp_foldlM_coinStep (t : ℕ) (r : List Bool) : +private theorem isBoundedComp_foldlM_coinStep (t : ℕ) (r : List Bool) : ∀ (i : ℕ) (cfg : FiniteConfig k Bool Control Oracle), (∀ op, (cfg.channels op).1.length ≤ i) → i + r.length ≤ t → IsBoundedComp t r.length (r.foldlM (coinStep M t) cfg) := by @@ -333,7 +335,7 @@ theorem isBoundedComp_foldlM_coinStep (t : ℕ) (r : List Bool) : /-- `coinProgram M t x r` is a `t`-bounded query program of depth `r.length` whenever `r.length ≤ t`. -/ -theorem isBoundedComp_coinProgram (t : ℕ) (x r : List Bool) (hr : r.length ≤ t) : +private theorem isBoundedComp_coinProgram (t : ℕ) (x r : List Bool) (hr : r.length ≤ t) : IsBoundedComp t r.length (coinProgram M t x r) := by unfold coinProgram refine IsBoundedComp.map _ (isBoundedComp_foldlM_coinStep M t r 0 @@ -379,14 +381,14 @@ def TreeStrategy.step : {d : ℕ} → TreeStrategy d → List Bool → List Bool | none => ([], ⟨0, PUnit.unit⟩) /-- Turn an initial `(depth, TreeStrategy)` pair into a `DetProver`. -/ -abbrev TreeStrategy.toDetProver (initTree : Sigma TreeStrategy) : DetProver where +private abbrev TreeStrategy.toDetProver (initTree : Sigma TreeStrategy) : DetProver where State := Sigma TreeStrategy init := initTree respond m s := s.2.step m /-- Universal `Prover Unit` for tree strategies with initial state `⟨0, PUnit.unit⟩`; its `.respond` operation depends only on the runtime `Sigma TreeStrategy` state. -/ -noncomputable abbrev treeProver : Prover Unit := +private noncomputable abbrev treeProver : Prover Unit := (TreeStrategy.toDetProver ⟨0, PUnit.unit⟩).toProver /-- Presample a depth-`d` `TreeStrategy` from a stateful randomized prover `Q : Prover Unit` @@ -429,7 +431,7 @@ private theorem mapM_lookup_eq [BEq α] [LawfulBEq α] (f : α → PMF β) (quer /-- Stepping a presampled tree of depth `d + 1` on `m ∈ queries` has the exact same distribution as running `Q.respond ((), m)` once, truncating the reply to `L` bits, and presampling a depth-`d` continuation tree from the resulting prover state. -/ -theorem presampleTree_step (Q : Prover Unit) (L : ℕ) (queries : List (List Bool)) (d : ℕ) +private theorem presampleTree_step (Q : Prover Unit) (L : ℕ) (queries : List (List Bool)) (d : ℕ) (s : Q.State) {m : List Bool} (hm : m ∈ queries) : (presampleTree Q L queries (d + 1) s).map (fun t => t.step m) = ((Q.respond ((), m)).run s).bind fun ys => diff --git a/Complexity/Computability/Complexity/Classes/NP/SelfReduction.lean b/Complexity/Computability/Complexity/Classes/NP/SelfReduction.lean index f07f34911..7c2eec106 100644 --- a/Complexity/Computability/Complexity/Classes/NP/SelfReduction.lean +++ b/Complexity/Computability/Complexity/Classes/NP/SelfReduction.lean @@ -90,7 +90,7 @@ theorem queryBound_mono : Monotone queryBound := fun _ _ h => by /-! ### Correctness -/ -theorem map_fst_foldl_selfReduceStep (D : CNF ℕ → Bool) (φ : CNF ℕ) (l : List ℕ) +private theorem map_fst_foldl_selfReduceStep (D : CNF ℕ → Bool) (φ : CNF ℕ) (l : List ℕ) (answers : List (Literal ℕ)) : (l.foldl (selfReduceStep D φ) answers).map Prod.fst = answers.map Prod.fst ++ l := by induction l generalizing answers with @@ -98,7 +98,7 @@ theorem map_fst_foldl_selfReduceStep (D : CNF ℕ → Bool) (φ : CNF ℕ) (l : | cons v l ih => simp [ih, selfReduceStep] /-- The self-reduction fixes the literal occurrences in order. -/ -theorem map_fst_selfReduce (D : CNF ℕ → Bool) (φ : CNF ℕ) : +private theorem map_fst_selfReduce (D : CNF ℕ → Bool) (φ : CNF ℕ) : (selfReduce D φ).map Prod.fst = φ.vars := by rw [selfReduce, map_fst_foldl_selfReduceStep, List.map_nil, List.nil_append] @@ -106,16 +106,16 @@ theorem length_search (D : CNF ℕ → Bool) (φ : CNF ℕ) : (search D φ).leng rw [search, List.length_map, ← map_fst_selfReduce D φ, List.length_map] /-- A formula with unit clauses holds exactly when the formula holds and the literals do. -/ -theorem eval_append_units (σ : ℕ → Bool) (φ : CNF ℕ) (answers : List (Literal ℕ)) : +private theorem eval_append_units (σ : ℕ → Bool) (φ : CNF ℕ) (answers : List (Literal ℕ)) : (φ ++ units answers).eval σ = true ↔ φ.eval σ = true ∧ ∀ l ∈ answers, σ l.1 = l.2 := by simp [units, CNF.eval_eq_true_iff, Clause.eval_eq_true_iff, or_imp, forall_and] -theorem length_encCNF_append (φ ψ : CNF ℕ) : +private theorem length_encCNF_append (φ ψ : CNF ℕ) : (encCNF (φ ++ ψ)).length = (encCNF φ).length + (encCNF ψ).length := by simp [encCNF] /-- A variable of a formula takes fewer bits than the formula. -/ -theorem length_encNat_le_of_mem_vars {φ : CNF ℕ} {v : ℕ} (hv : v ∈ φ.vars) : +private theorem length_encNat_le_of_mem_vars {φ : CNF ℕ} {v : ℕ} (hv : v ∈ φ.vars) : (encNat v).length ≤ (encCNF φ).length := by obtain ⟨l, hl, rfl⟩ := List.mem_map.1 hv obtain ⟨c, hc, hl⟩ := List.mem_flatten.1 hl @@ -125,7 +125,7 @@ theorem length_encNat_le_of_mem_vars {φ : CNF ℕ} {v : ℕ} (hv : v ∈ φ.var /-- The unit clause of a literal on `v` takes `8 b + 11` bits, where `b` is the length of the binary digits of `v`. -/ -theorem length_encCNF_unit (l : Literal ℕ) : +private theorem length_encCNF_unit (l : Literal ℕ) : (encCNF [[l]]).length = 8 * (encNat l.1).length + 11 := by simp only [encCNF, encList_cons, encList_nil, List.append_nil, length_frame, length_encPair, encBool_apply, List.length_singleton] @@ -133,14 +133,14 @@ theorem length_encCNF_unit (l : Literal ℕ) : /-- The unit clause of a literal on a variable of `φ` takes at most `8 L + 11` bits, where `L` is the length of `φ`. -/ -theorem length_encCNF_unit_le {φ : CNF ℕ} {l : Literal ℕ} (hl : l.1 ∈ φ.vars) : +private theorem length_encCNF_unit_le {φ : CNF ℕ} {l : Literal ℕ} (hl : l.1 ∈ φ.vars) : (encCNF [[l]]).length ≤ 8 * (encCNF φ).length + 11 := by have := length_encNat_le_of_mem_vars hl rw [length_encCNF_unit] omega /-- The formulas that the self-reduction asks about are no longer than `queryBound`. -/ -theorem length_query_le {φ : CNF ℕ} {answers : List (Literal ℕ)} +private theorem length_query_le {φ : CNF ℕ} {answers : List (Literal ℕ)} (hanswers : ∀ l ∈ answers, l.1 ∈ φ.vars) (hlen : answers.length ≤ φ.vars.length) {v : ℕ} (hv : v ∈ φ.vars) : (encCNF (φ ++ units answers ++ [[(v, true)]])).length ≤ queryBound (encCNF φ).length := by @@ -165,7 +165,7 @@ theorem length_query_le {φ : CNF ℕ} {answers : List (Literal ℕ)} /-- With answers correct on the queries, the self-reduction keeps a satisfiable formula satisfiable. -/ -theorem satisfiable_foldl_selfReduceStep {D : CNF ℕ → Bool} {φ : CNF ℕ} +private theorem satisfiable_foldl_selfReduceStep {D : CNF ℕ → Bool} {φ : CNF ℕ} (hD : ∀ ψ, (encCNF ψ).length ≤ queryBound (encCNF φ).length → (D ψ = true ↔ ψ ∈ SAT)) (l : List ℕ) (hl : ∀ v ∈ l, v ∈ φ.vars) (answers : List (Literal ℕ)) (hanswers : ∀ a ∈ answers, a.1 ∈ φ.vars) (hlen : answers.length + l.length ≤ φ.vars.length) diff --git a/Complexity/Computability/Complexity/Classes/NP/Witness.lean b/Complexity/Computability/Complexity/Classes/NP/Witness.lean index 59fbd36ee..52dc5cbb0 100644 --- a/Complexity/Computability/Complexity/Classes/NP/Witness.lean +++ b/Complexity/Computability/Complexity/Classes/NP/Witness.lean @@ -222,7 +222,7 @@ theorem length_selectDistinct_replicate (l : List γ) : /-- The entries of `l` selected by the mask of a set `S` of entries of `l`, followed by any bits, are the elements of `S`. -/ -theorem toFinset_selectDistinct_map_append {l : List γ} {S : Finset γ} (hS : ∀ v ∈ S, v ∈ l) +private theorem toFinset_selectDistinct_map_append {l : List γ} {S : Finset γ} (hS : ∀ v ∈ S, v ∈ l) (u : List Bool) : (selectDistinct l (l.map (fun v => decide (v ∈ S)) ++ u)).toFinset = S := by have hget : ∀ v ∈ l, (l.map (fun v => decide (v ∈ S)) ++ u).getD (l.idxOf v) false = decide (v ∈ S) := by diff --git a/Complexity/Computability/Complexity/Classes/Oracle.lean b/Complexity/Computability/Complexity/Classes/Oracle.lean index b7d8e1d97..eab7088ce 100644 --- a/Complexity/Computability/Complexity/Classes/Oracle.lean +++ b/Complexity/Computability/Complexity/Classes/Oracle.lean @@ -95,7 +95,7 @@ def queriesWith (answer : (q : ι) → spec q) : OracleComp spec α → List ι /-- A sequence makes the requests of its first part, then those of the continuation selected by the first result. -/ -theorem queriesWith_bind (answer : (q : ι) → spec q) (program : OracleComp spec α) +private theorem queriesWith_bind (answer : (q : ι) → spec q) (program : OracleComp spec α) (next : α → OracleComp spec β) : queriesWith answer (program >>= next) = queriesWith answer program ++ queriesWith answer (next (interpret (m := Id) answer program)) := by diff --git a/Complexity/Computability/Complexity/Classes/Oracle/BakerGillSolovay.lean b/Complexity/Computability/Complexity/Classes/Oracle/BakerGillSolovay.lean index 629f035b3..6d6b49273 100644 --- a/Complexity/Computability/Complexity/Classes/Oracle/BakerGillSolovay.lean +++ b/Complexity/Computability/Complexity/Classes/Oracle/BakerGillSolovay.lean @@ -88,7 +88,7 @@ def Candidate.verdict (candidate : Candidate) (n : ℕ) : WordQueryComp Unit Boo (fun op word => OracleComp.query (op, word)) (candidate.clock n) (List.replicate n true) /-- A candidate makes at most one request per instruction. -/ -theorem Candidate.length_queriesWith_verdict_le (candidate : Candidate) (n : ℕ) +private theorem Candidate.length_queriesWith_verdict_le (candidate : Candidate) (n : ℕ) (A : Set (List Bool)) : (OracleComp.queriesWith (languageOracle A) (candidate.verdict n)).length ≤ candidate.clock n := by @@ -97,7 +97,7 @@ theorem Candidate.length_queriesWith_verdict_le (candidate : Candidate) (n : ℕ (fun choices => choices false) _ _ _ /-- Every clock is eventually below `2 ^ n`. -/ -theorem Candidate.eventually_clock_lt (candidate : Candidate) : +private theorem Candidate.eventually_clock_lt (candidate : Candidate) : ∀ᶠ n in Filter.atTop, candidate.clock n < 2 ^ n := PolynomiallyBounded.eventually_lt_two_pow (f := candidate.clock) (by unfold Candidate.clock; fun_prop) @@ -131,14 +131,14 @@ theorem exists_unaryLengthLanguage_notMem_PWithOracle : namespace BakerGillSolovay /-- Tracks whether every symbol read so far is `true`, and emits the verdict at the end. -/ -def allTrue : Transducer Bool Bool where +private def allTrue : Transducer Bool Bool where q₀ := true step q b := (q && b, []) final q := [q] length_step_le _ _ := by simp length_final_le _ := by simp -theorem allTrue_run (q : Bool) (x : List Bool) : allTrue.run q x = [q && x.all id] := by +private theorem allTrue_run (q : Bool) (x : List Bool) : allTrue.run q x = [q && x.all id] := by induction x generalizing q with | nil => simp [allTrue] | cons b x ih => @@ -147,7 +147,7 @@ theorem allTrue_run (q : Bool) (x : List Bool) : allTrue.run q x = [q && x.all i /-- Whether the first word consists of `true` symbols only, beside a Boolean, in polynomial time. -/ -theorem computableTidilyInPolyTime_all_and : +private theorem computableTidilyInPolyTime_all_and : ComputableTidilyInPolyTime (fun pair : (List Bool × List Bool) × Bool => pair.1.1.all id && pair.2) (encPair (encPair encBits encBits) encBool) encBool := by diff --git a/Complexity/Computability/Complexity/Classes/Oracle/Deterministic.lean b/Complexity/Computability/Complexity/Classes/Oracle/Deterministic.lean index 944fdcbe3..6b6e573d6 100644 --- a/Complexity/Computability/Complexity/Classes/Oracle/Deterministic.lean +++ b/Complexity/Computability/Complexity/Classes/Oracle/Deterministic.lean @@ -118,7 +118,8 @@ def relabel (e : State ≃ State') (machine : MultiTapePTM k Symbol State Oracle variable [DecidableEq Oracle] /-- Relabelling commutes with the run program, for every coin and request program. -/ -theorem runConfigFrom_relabel {Query : Type} {spec : OracleSpec.{0, 0} Query} (e : State ≃ State') +private theorem runConfigFrom_relabel {Query : Type} {spec : OracleSpec.{0, 0} Query} + (e : State ≃ State') (machine : MultiTapePTM k Symbol State Oracle) (coin : OracleComp spec Bool) (query : Oracle → List Symbol → OracleComp spec (List Symbol)) (fuel : ℕ) (cfg : Config k Symbol State Oracle input) : @@ -143,7 +144,7 @@ theorem runFrom_relabel {Query : Type} {spec : OracleSpec.{0, 0} Query} (e : Sta simp only [runFrom, runConfigFrom_relabel, Functor.map_map, Config.mapState_tapes_output] /-- Relabelling preserves the output program of every run from the initial configuration. -/ -theorem run_relabel {Query : Type} {spec : OracleSpec.{0, 0} Query} (e : State ≃ State') +private theorem run_relabel {Query : Type} {spec : OracleSpec.{0, 0} Query} (e : State ≃ State') (machine : MultiTapePTM k Symbol State Oracle) (coin : OracleComp spec Bool) (query : Oracle → List Symbol → OracleComp spec (List Symbol)) (fuel : ℕ) (input : List Symbol) : @@ -220,7 +221,8 @@ variable {Operation α β : Type} [DecidableEq Operation] {input : α ↪ List B omit [DecidableEq Operation] in /-- A deterministic program against a deterministic oracle returns a point mass and keeps the oracle's state. -/ -theorem run_interpret_interpret_query {σ : Type} (answer : Operation × List Bool → List Bool) +private theorem run_interpret_interpret_query {σ : Type} + (answer : Operation × List Bool → List Bool) (program : WordQueryComp Operation β) (s : σ) : (OracleComp.interpret (ProbOracleComp.handler (fun n => StateT.lift (ProbComp.unifOracle n)) (fun q s => PMF.pure (answer q, s))) diff --git a/Complexity/Computability/Complexity/Classes/Oracle/Replay.lean b/Complexity/Computability/Complexity/Classes/Oracle/Replay.lean index e252986fe..03b154ac5 100644 --- a/Complexity/Computability/Complexity/Classes/Oracle/Replay.lean +++ b/Complexity/Computability/Complexity/Classes/Oracle/Replay.lean @@ -81,7 +81,7 @@ def replayOutput (input answers : List Bool) : List Bool := (machine.replayConfig input answers).tapes.output /-- A supplied bit is equivalent to a constant one-bit oracle for this instruction. -/ -theorem replyStep_eq_answerStep (cfg : FiniteConfig k Bool Control Operation) (bit : Bool) : +private theorem replyStep_eq_answerStep (cfg : FiniteConfig k Bool Control Operation) (bit : Bool) : machine.replyStep cfg bit = machine.answerStep (fun _ => [bit]) cfg := (machine.answerStep_bit (fun _ => bit) cfg).symm @@ -107,7 +107,7 @@ theorem replayFrom_append (cfg : FiniteConfig k Bool Control Operation) List.foldl_append /-- Appending a bit executes exactly one further instruction. -/ -theorem replayConfig_append_singleton (input answers : List Bool) (bit : Bool) : +private theorem replayConfig_append_singleton (input answers : List Bool) (bit : Bool) : machine.replayConfig input (answers ++ [bit]) = machine.replyStep (machine.replayConfig input answers) bit := by simp only [replayConfig, replayFrom, List.foldl_append, List.foldl_cons, List.foldl_nil] @@ -121,7 +121,7 @@ theorem replayPrefix_succ (input answers : List Bool) (index : ℕ) rw [List.take_succ_eq_append_getElem hindex, replayConfig_append_singleton] /-- Every replayed instruction preserves the native one-bit-reply storage bound. -/ -theorem spaceBound_replyStep {inputSize steps : ℕ} +private theorem spaceBound_replyStep {inputSize steps : ℕ} {cfg : FiniteConfig k Bool Control Operation} (h : FiniteConfig.SpaceBound inputSize steps 1 cfg) (bit : Bool) : FiniteConfig.SpaceBound inputSize (steps + 1) 1 (machine.replyStep cfg bit) := by @@ -129,7 +129,7 @@ theorem spaceBound_replyStep {inputSize steps : ℕ} exact machine.spaceBound_answerStep (fun _ => bit) h /-- A transcript of length `r` executes `r` instructions with replies of length one. -/ -theorem spaceBound_replayFrom {inputSize steps : ℕ} +private theorem spaceBound_replayFrom {inputSize steps : ℕ} {cfg : FiniteConfig k Bool Control Operation} (h : FiniteConfig.SpaceBound inputSize steps 1 cfg) (answers : List Bool) : FiniteConfig.SpaceBound inputSize (steps + answers.length) 1 @@ -141,13 +141,13 @@ theorem spaceBound_replayFrom {inputSize steps : ℕ} Nat.add_left_comm, Nat.add_comm] using ih (machine.spaceBound_replyStep h bit) /-- Replay from the initial configuration has linear storage in the input and transcript. -/ -theorem spaceBound_replayConfig (input answers : List Bool) : +private theorem spaceBound_replayConfig (input answers : List Bool) : FiniteConfig.SpaceBound input.length answers.length 1 (machine.replayConfig input answers) := by simpa only [replayConfig, Nat.zero_add] using machine.spaceBound_replayFrom (FiniteConfig.spaceBound_init machine.initial input 1) answers /-- A pending request contains at most one symbol per elapsed native instruction. -/ -theorem length_pendingRequest_replayConfig_le (input answers : List Bool) : +private theorem length_pendingRequest_replayConfig_le (input answers : List Bool) : (machine.pendingRequest (machine.replayConfig input answers)).length ≤ answers.length := machine.length_pendingRequest_le (machine.spaceBound_replayConfig input answers) @@ -246,7 +246,7 @@ def oracleReplies (g : List Bool → Bool) (fuel : ℕ) (input : List Bool) : Li machine.oracleRepliesFrom g (FiniteConfig.init machine.initial input) fuel /-- A canonical transcript has exactly one bit per clocked instruction. -/ -theorem length_oracleRepliesFrom (g : List Bool → Bool) +private theorem length_oracleRepliesFrom (g : List Bool → Bool) (cfg : FiniteConfig k Bool Control Operation) (fuel : ℕ) : (machine.oracleRepliesFrom g cfg fuel).length = fuel := by induction fuel generalizing cfg with @@ -259,7 +259,7 @@ theorem length_oracleReplies (g : List Bool → Bool) (fuel : ℕ) (input : List machine.length_oracleRepliesFrom g _ fuel /-- Canonical transcripts are consistent under truncation of their clock. -/ -theorem take_oracleRepliesFrom (g : List Bool → Bool) +private theorem take_oracleRepliesFrom (g : List Bool → Bool) (cfg : FiniteConfig k Bool Control Operation) (fuel index : ℕ) : (machine.oracleRepliesFrom g cfg fuel).take index = machine.oracleRepliesFrom g cfg (min index fuel) := by @@ -281,7 +281,7 @@ private theorem replyStep_oracleBit (g : List Bool → Bool) split <;> rfl /-- Canonical replay recovers the entire finite configuration, not only its output. -/ -theorem replayFrom_oracleRepliesFrom (g : List Bool → Bool) +private theorem replayFrom_oracleRepliesFrom (g : List Bool → Bool) (cfg : FiniteConfig k Bool Control Operation) (fuel : ℕ) : machine.replayFrom cfg (machine.oracleRepliesFrom g cfg fuel) = (machine.answerStep (fun q => [g q.2]))^[fuel] cfg := by @@ -300,7 +300,7 @@ theorem replayConfig_oracleReplies (g : List Bool → Bool) (fuel : ℕ) (input machine.replayFrom_oracleRepliesFrom g _ fuel /-- A canonical prefix recovers the configuration after the corresponding elapsed instructions. -/ -theorem replayPrefix_oracleReplies (g : List Bool → Bool) (fuel : ℕ) (input : List Bool) +private theorem replayPrefix_oracleReplies (g : List Bool → Bool) (fuel : ℕ) (input : List Bool) (index : ℕ) : machine.replayPrefix input (machine.oracleReplies g fuel input) index = (machine.answerStep (fun q => [g q.2]))^[min index fuel] @@ -311,7 +311,7 @@ theorem replayPrefix_oracleReplies (g : List Bool → Bool) (fuel : ℕ) (input /-- The bit of a canonical transcript at a live clock index is the pending oracle answer, with `false` at local or halted instructions. -/ -theorem getD_oracleRepliesFrom (g : List Bool → Bool) +private theorem getD_oracleRepliesFrom (g : List Bool → Bool) (cfg : FiniteConfig k Bool Control Operation) (fuel index : ℕ) (hindex : index < fuel) : (machine.oracleRepliesFrom g cfg fuel).getD index false = let current := (machine.answerStep (fun q => [g q.2]))^[index] cfg diff --git a/Complexity/Computability/Complexity/Classes/Oracle/Simulation.lean b/Complexity/Computability/Complexity/Classes/Oracle/Simulation.lean index 400918af8..9d86af413 100644 --- a/Complexity/Computability/Complexity/Classes/Oracle/Simulation.lean +++ b/Complexity/Computability/Complexity/Classes/Oracle/Simulation.lean @@ -108,7 +108,7 @@ theorem _root_.Cslib.OracleComp.interpret_id_iterate {State Query : Type} rfl /-- The interpreted native instruction, with every coin `false`, is `answerStep`. -/ -theorem interpret_finiteStep (answer : Operation × List Bool → List Bool) +private theorem interpret_finiteStep (answer : Operation × List Bool → List Bool) (cfg : FiniteConfig k Bool Control Operation) : OracleComp.interpret (m := Id) answer (MultiTapeMachine.finiteStep machine (fun choices => choices <$> (pure false : OracleComp _ Bool)) diff --git a/Complexity/Computability/Complexity/Classes/Oracle/TQBF.lean b/Complexity/Computability/Complexity/Classes/Oracle/TQBF.lean index efbbb4af3..76bc00ca7 100644 --- a/Complexity/Computability/Complexity/Classes/Oracle/TQBF.lean +++ b/Complexity/Computability/Complexity/Classes/Oracle/TQBF.lean @@ -79,14 +79,14 @@ number of formulas still expected. -/ def wfStep (s : Bool × ℕ) (t : QBF.Kind × ℕ) : Bool × ℕ := (s.1 && decide (s.2 ≠ 0) && tokenOk t, s.2 - 1 + arity t.1) -theorem foldl_wfStep_false (ts : List (QBF.Kind × ℕ)) (n : ℕ) : +private theorem foldl_wfStep_false (ts : List (QBF.Kind × ℕ)) (n : ℕ) : (ts.foldl wfStep (false, n)).1 = false := by induction ts generalizing n with | nil => rfl | cons t ts ih => exact ih _ /-- Reading the tokens of a formula consumes one expected formula. -/ -theorem foldl_wfStep_tokens (φ : QBF ℕ) (n : ℕ) (rest : List (QBF.Kind × ℕ)) : +private theorem foldl_wfStep_tokens (φ : QBF ℕ) (n : ℕ) (rest : List (QBF.Kind × ℕ)) : (φ.tokens ++ rest).foldl wfStep (true, n + 1) = rest.foldl wfStep (true, n) := by induction φ generalizing n rest with | var v => simp [QBF.tokens, wfStep, tokenOk, arity] @@ -115,7 +115,7 @@ theorem foldl_wfStep_tokens (φ : QBF ℕ) (n : ℕ) (rest : List (QBF.Kind × simpa using ih n rest /-- The concatenated tokens of `n` formulas are accepted. -/ -theorem foldl_wfStep_flatten (φs : List (QBF ℕ)) : +private theorem foldl_wfStep_flatten (φs : List (QBF ℕ)) : (φs.map QBF.tokens).flatten.foldl wfStep (true, φs.length) = (true, 0) := by induction φs with | nil => rfl @@ -179,7 +179,7 @@ def kindOfIndex : ℕ → QBF.Kind | 6 => .ex | _ => .all -theorem kindIndex_kindOfIndex : ∀ n, kindIndex (kindOfIndex n) = min n 7 +private theorem kindIndex_kindOfIndex : ∀ n, kindIndex (kindOfIndex n) = min n 7 | 0 | 1 | 2 | 3 | 4 | 5 | 6 => rfl | n + 7 => by simp [kindOfIndex, kindIndex] @@ -212,7 +212,8 @@ theorem wellFormed_iff (ts : List (QBF.Kind × ℕ)) : · rintro ⟨φ, rfl⟩ exact ⟨[φ], rfl, by simp⟩ -theorem wellFormed_pt : ComputableTidilyInPolyTime wellFormed (encList encToken) encBool := by +private theorem wellFormed_pt : ComputableTidilyInPolyTime wellFormed + (encList encToken) encBool := by have hstep : ComputableTidilyInPolyTime (fun p : (Bool × ℕ) × (QBF.Kind × ℕ) => wfStep p.1 p.2) (encPair (encPair encBool encUnary) encToken) (encPair encBool encUnary) := by have hok : ComputableTidilyInPolyTime tokenOk encToken encBool := by @@ -285,7 +286,7 @@ open Classical in noncomputable def decodeQBF (w : List Bool) : QBF ℕ := if h : ∃ φ, encQBF φ = w then h.choose else .bot -theorem encQBF_decodeQBF (w : List Bool) : +private theorem encQBF_decodeQBF (w : List Bool) : encQBF (decodeQBF w) = if isCode w then w else encQBF .bot := by unfold decodeQBF split_ifs with h₁ h₂ h₃ @@ -298,7 +299,7 @@ theorem decodeQBF_pt : ComputableTidilyInPolyTime decodeQBF encBits encQBF := (ComputableTidilyInPolyTime.ite' isCode_pt ComputableTidilyInPolyTime.id' (ComputableTidilyInPolyTime.const (encQBF .bot))).of_enc_eq fun w => encQBF_decodeQBF w -theorem decodeQBF_encQBF (φ : QBF ℕ) : decodeQBF (encQBF φ) = φ := +private theorem decodeQBF_encQBF (φ : QBF ℕ) : decodeQBF (encQBF φ) = φ := encQBF.injective (by simp [encQBF_decodeQBF, (isCode_iff _).mpr ⟨φ, rfl⟩]) end Cslib.Complexity.TQBF diff --git a/Complexity/Computability/Complexity/Classes/PH/Closure.lean b/Complexity/Computability/Complexity/Classes/PH/Closure.lean index 85bea1f50..ced794ad0 100644 --- a/Complexity/Computability/Complexity/Classes/PH/Closure.lean +++ b/Complexity/Computability/Complexity/Classes/PH/Closure.lean @@ -104,7 +104,7 @@ theorem alternation_splitAlternatingBlocks (ns : List (ℕ × ℕ)) (q : Bool) /-- Splitting paired blocks is polynomial-time when their lengths are fixed polynomials of a computed unary size. -/ -theorem computableTidilyInPolyTime_splitAlternatingBlocks {γ : Type} +private theorem computableTidilyInPolyTime_splitAlternatingBlocks {γ : Type} {encIn : γ ↪ List Bool} (ps : List (Polynomial ℕ × Polynomial ℕ)) {N : γ → ℕ} (hN : ComputableTidilyInPolyTime N encIn encUnary) {W : γ → List Bool} (hW : ComputableTidilyInPolyTime W encIn encBits) : diff --git a/Complexity/Computability/Complexity/Classes/PH/Kannan.lean b/Complexity/Computability/Complexity/Classes/PH/Kannan.lean index 9fd51493c..db86ff527 100644 --- a/Complexity/Computability/Complexity/Classes/PH/Kannan.lean +++ b/Complexity/Computability/Complexity/Classes/PH/Kannan.lean @@ -119,33 +119,34 @@ def arity (k n : ℕ) : ℕ := (k + 3) * (Nat.log 2 (n + 1) + 1) /-- The number of gates that the hard functions at input length `n` exceed. -/ def threshold (k n : ℕ) : ℕ := (n + 1) ^ (k + 1) -theorem two_pow_arity (k n : ℕ) : 2 ^ arity k n = (2 ^ (Nat.log 2 (n + 1) + 1)) ^ (k + 3) := by +private theorem two_pow_arity (k n : ℕ) : 2 ^ arity k n = (2 ^ (Nat.log 2 (n + 1) + 1)) ^ + (k + 3) := by rw [arity, Nat.mul_comm, pow_mul] -theorem two_pow_arity_le (k n : ℕ) : 2 ^ arity k n ≤ 2 ^ (k + 3) * (n + 1) ^ (k + 3) := by +private theorem two_pow_arity_le (k n : ℕ) : 2 ^ arity k n ≤ 2 ^ (k + 3) * (n + 1) ^ (k + 3) := by rw [two_pow_arity, ← Nat.mul_pow, pow_succ 2 (Nat.log 2 (n + 1)), Nat.mul_comm _ 2] exact Nat.pow_le_pow_left (Nat.mul_le_mul_left 2 (Nat.pow_log_le_self 2 (Nat.succ_ne_zero n))) _ -theorem lt_two_pow_arity (k n : ℕ) : (n + 1) ^ (k + 3) < 2 ^ arity k n := by +private theorem lt_two_pow_arity (k n : ℕ) : (n + 1) ^ (k + 3) < 2 ^ arity k n := by rw [two_pow_arity] exact Nat.pow_lt_pow_left (Nat.lt_pow_succ_log_self (by norm_num) _) (by omega) -theorem arity_le (k n : ℕ) : arity k n ≤ (k + 3) * (n + 1) := +private theorem arity_le (k n : ℕ) : arity k n ≤ (k + 3) * (n + 1) := Nat.mul_le_mul_left _ (Nat.succ_le_of_lt (Nat.log_lt_self 2 (Nat.succ_ne_zero n))) /-- The hard functions have enough inputs for `2 ^ m / m` to exceed the threshold. -/ -theorem threshold_mul_arity_lt {k n : ℕ} (hn : k + 3 ≤ n + 1) : +private theorem threshold_mul_arity_lt {k n : ℕ} (hn : k + 3 ≤ n + 1) : threshold k n * arity k n < 2 ^ arity k n := by refine lt_of_le_of_lt ?_ (lt_two_pow_arity k n) calc threshold k n * arity k n ≤ (n + 1) ^ (k + 1) * ((n + 1) * (n + 1)) := Nat.mul_le_mul_left _ ((arity_le k n).trans (Nat.mul_le_mul_right _ hn)) _ = (n + 1) ^ (k + 3) := by ring -theorem le_arity (k n : ℕ) : Nat.log 2 (n + 1) + 1 ≤ arity k n := +private theorem le_arity (k n : ℕ) : Nat.log 2 (n + 1) + 1 ≤ arity k n := Nat.le_mul_of_pos_left _ (by omega) /-- The hard functions eventually have no more inputs than the instance. -/ -theorem eventually_arity_le (k : ℕ) : ∀ᶠ n in atTop, arity k n ≤ n := by +private theorem eventually_arity_le (k : ℕ) : ∀ᶠ n in atTop, arity k n ≤ n := by filter_upwards [Nat.eventually_mul_log_le (2 * (k + 3)) one_lt_two, eventually_ge_atTop 4] with n hn h4 have hlog : Nat.log 2 (n + 1) ≤ Nat.log 2 n + 1 := by @@ -157,7 +158,7 @@ theorem eventually_arity_le (k : ℕ) : ∀ᶠ n in atTop, arity k n ≤ n := by _ ≤ n := hn /-- The hard functions eventually have at least `N` inputs. -/ -theorem eventually_le_arity (k N : ℕ) : ∀ᶠ n in atTop, N ≤ arity k n := by +private theorem eventually_le_arity (k N : ℕ) : ∀ᶠ n in atTop, N ≤ arity k n := by filter_upwards [eventually_ge_atTop (2 ^ N)] with n hn have : N ≤ Nat.log 2 (n + 1) := (Nat.le_log_iff_pow_le (by norm_num) (by omega)).2 (by omega) exact this.trans ((Nat.le_succ _).trans (le_arity k n)) @@ -204,7 +205,7 @@ theorem exists_isFirstHard {k n : ℕ} (h : ∃ T, IsHard k n T) : ∃ T, IsFirs exact ⟨T, hT, fun T' hT' => hv ▸ Nat.find_min' hex ⟨T', hT', rfl⟩⟩ /-- The truth table of a function, as a list, is read back as the function. -/ -theorem tableFunction_ofFn_truthTable (m : ℕ) (f : BooleanFunction m) : +private theorem tableFunction_ofFn_truthTable (m : ℕ) (f : BooleanFunction m) : tableFunction m (List.ofFn (MCSP.truthTable m f)) = f := by funext y exact (MCSP.tableValue_ofFn ⟨m, MCSP.truthTable m f, 0⟩ y).trans @@ -228,7 +229,8 @@ theorem eventually_exists_isHard (k : ℕ) : ∀ᶠ n in atTop, ∃ T, IsHard k /-- The slice of Kannan's language is the function of the first hard truth table on the first `arity k n` bits. -/ -theorem slice_language {k n : ℕ} {T : List Bool} (hT : IsFirstHard k n T) (x : Fin n → Bool) : +private theorem slice_language {k n : ℕ} {T : List Bool} (hT : IsFirstHard k n T) + (x : Fin n → Bool) : (language k).slice n x = MCSP.tableValue T ((List.ofFn x).take (arity k n)) := by rw [Bool.eq_iff_iff, Language.slice_eq_true_iff] change (∃ T', IsFirstHard k (List.ofFn x).length T' ∧ _) ↔ _ @@ -236,10 +238,10 @@ theorem slice_language {k n : ℕ} {T : List Bool} (hT : IsFirstHard k n T) (x : exact ⟨fun ⟨T', hT', h⟩ => hT.unique hT' ▸ h, fun h => ⟨T, hT, h⟩⟩ /-- Feeding the first `m ≤ n` inputs from `m` variables and the others with `false`. -/ -def restriction (m n : ℕ) (j : Fin n) : Fin m ⊕ Bool := +private def restriction (m n : ℕ) (j : Fin n) : Fin m ⊕ Bool := if h : j.val < m then .inl ⟨j.val, h⟩ else .inr false -theorem take_ofFn_substitute_restriction {m n : ℕ} (h : m ≤ n) (y : Fin m → Bool) : +private theorem take_ofFn_substitute_restriction {m n : ℕ} (h : m ≤ n) (y : Fin m → Bool) : (List.ofFn (substitute (restriction m n) y)).take m = List.ofFn y := by refine List.ext_getElem (by simp [h]) fun i h₁ h₂ => ?_ simp only [List.length_ofFn] at h₂ @@ -247,7 +249,7 @@ theorem take_ofFn_substitute_restriction {m n : ℕ} (h : m ≤ n) (y : Fin m /-- The slices of Kannan's language need more than `threshold k n - 2` gates where a hard truth table exists on at most `n` inputs. -/ -theorem threshold_lt_complexity_slice {k n : ℕ} {T : List Bool} (hT : IsFirstHard k n T) +private theorem threshold_lt_complexity_slice {k n : ℕ} {T : List Bool} (hT : IsFirstHard k n T) (hm : arity k n ≤ n) : threshold k n < complexity interpretation (single ((language k).slice n)) + 2 := by refine hT.1.2.trans_le (le_of_eq_of_le ?_ @@ -274,15 +276,15 @@ theorem language_notMem_SIZE (k c : ℕ) : language k ∉ SIZE fun n => c * (n + /-! ### Truth tables in MCSP -/ /-- The MCSP instance of a truth table of length `2 ^ m`. -/ -def tableInstance (m s : ℕ) (T : List Bool) (hT : T.length = 2 ^ m) : MCSP.Instance := +private def tableInstance (m s : ℕ) (T : List Bool) (hT : T.length = 2 ^ m) : MCSP.Instance := ⟨m, fun i => T[i.val]'(by rw [hT]; exact i.isLt), s⟩ -theorem ofFn_tableInstance {m s : ℕ} {T : List Bool} (hT : T.length = 2 ^ m) : +private theorem ofFn_tableInstance {m s : ℕ} {T : List Bool} (hT : T.length = 2 ^ m) : List.ofFn (tableInstance m s T hT).table = T := by change List.ofFn (fun i : Fin (2 ^ m) => T[i.val]'(by rw [hT]; exact i.isLt)) = T exact List.ext_getElem (by simp [hT]) fun _ _ _ => by simp -theorem function_tableInstance {m s : ℕ} {T : List Bool} (hT : T.length = 2 ^ m) : +private theorem function_tableInstance {m s : ℕ} {T : List Bool} (hT : T.length = 2 ^ m) : (tableInstance m s T hT).function = tableFunction m T := by funext y rw [← MCSP.tableValue_ofFn, ofFn_tableInstance] @@ -290,7 +292,7 @@ theorem function_tableInstance {m s : ℕ} {T : List Bool} (hT : T.length = 2 ^ /-- An accepted certificate for a truth table of length `2 ^ m` bounds the complexity of its function. -/ -theorem complexity_le_of_tableVerifier {m s : ℕ} {T c : List Bool} (hT : T.length = 2 ^ m) +private theorem complexity_le_of_tableVerifier {m s : ℕ} {T c : List Bool} (hT : T.length = 2 ^ m) (h : MCSP.tableVerifier ((T, s), c) = true) : complexity interpretation (single (tableFunction m T)) ≤ s := by have := MCSP.mem_of_verifier_eq_true (x := tableInstance m s T hT) (w := c) @@ -299,7 +301,7 @@ theorem complexity_le_of_tableVerifier {m s : ℕ} {T c : List Bool} (hT : T.len /-- A truth table of length `2 ^ m` whose function has at most `s` gates has a certificate of length `certLength m (MCSP.budget m s)`, accepted whatever bits follow it. -/ -theorem exists_tableVerifier_append {m s : ℕ} {T : List Bool} (hT : T.length = 2 ^ m) +private theorem exists_tableVerifier_append {m s : ℕ} {T : List Bool} (hT : T.length = 2 ^ m) (h : complexity interpretation (single (tableFunction m T)) ≤ s) : ∃ u : List Bool, u.length = certLength m (MCSP.budget m s) ∧ ∀ extra, MCSP.tableVerifier ((T, s), u ++ extra) = true := by @@ -317,7 +319,7 @@ def tableBound (k n : ℕ) : ℕ := 2 ^ (k + 3) * (n + 1) ^ (k + 3) /-- The length of the blocks holding circuits. -/ def certBound (k n : ℕ) : ℕ := certLength ((k + 3) * (n + 1)) ((n + 1) ^ (k + 1)) -theorem certLength_le_certBound (k n : ℕ) : +private theorem certLength_le_certBound (k n : ℕ) : certLength (arity k n) (MCSP.budget (arity k n) (threshold k n)) ≤ certBound k n := by have hm := arity_le k n have hs : MCSP.budget (arity k n) (threshold k n) ≤ (n + 1) ^ (k + 1) := Nat.min_le_left _ _ @@ -343,7 +345,7 @@ def verifier (k : ℕ) (p : List Bool × List Bool) : Bool := p.2.drop (2 * tableBound k p.1.length + certBound k p.1.length)))) && MCSP.tableValue (table k p.1.length p.2) (p.1.take (arity k p.1.length)) -theorem verifier_append {k : ℕ} (x : List Bool) {w₁ w₂ : List Bool} +private theorem verifier_append {k : ℕ} (x : List Bool) {w₁ w₂ : List Bool} (h₁ : w₁.length = tableBound k x.length) (h₂ : w₂.length = tableBound k x.length + certBound k x.length) (w₃ : List Bool) : verifier k (x, w₁ ++ (w₂ ++ w₃)) = @@ -369,11 +371,12 @@ theorem verifier_append {k : ℕ} (x : List Bool) {w₁ w₂ : List Bool} exact List.drop_left' (by rw [List.length_append, h₁, h₂]; ring) simp only [verifier, hw₁, hw₂, hc, hc'] -theorem length_table {k n : ℕ} {w : List Bool} (hw : 2 ^ arity k n ≤ w.length) : +private theorem length_table {k n : ℕ} {w : List Bool} (hw : 2 ^ arity k n ≤ w.length) : (table k n w).length = 2 ^ arity k n := by rw [table, List.length_take, Nat.min_eq_left hw] -theorem table_append {k n : ℕ} {T : List Bool} (hT : T.length = 2 ^ arity k n) (w : List Bool) : +private theorem table_append {k n : ℕ} {T : List Bool} (hT : T.length = 2 ^ arity k n) + (w : List Bool) : table k n (T ++ w) = T := by rw [table, ← hT, List.take_left] @@ -394,7 +397,7 @@ noncomputable def certPoly (k : ℕ) : Polynomial ℕ := simp [certPoly, certBound, certLength] /-- The verifier verifies Kannan's language through three alternating blocks of certificates. -/ -theorem isAlternatingVerifier_verifier (k : ℕ) : +private theorem isAlternatingVerifier_verifier (k : ℕ) : IsAlternatingVerifier encBits true [tablePoly k, tablePoly k + certPoly k, certPoly k] (verifier k) (language k) := by intro x @@ -488,13 +491,13 @@ theorem ofBits_reverse (w : List Bool) : ofBits w.reverse = BitString.binaryValu open ComputableTidilyInPolyTime in /-- The binary value of a word is polynomial-time, in binary. -/ -theorem computableTidilyInPolyTime_binaryValue : +private theorem computableTidilyInPolyTime_binaryValue : ComputableTidilyInPolyTime BitString.binaryValue encBits encNat := bitsBinaryValue open ComputableTidilyInPolyTime in /-- The verifier for Kannan's language is polynomial-time. -/ -theorem computableTidilyInPolyTime_verifier (k : ℕ) : +private theorem computableTidilyInPolyTime_verifier (k : ℕ) : ComputableTidilyInPolyTime (verifier k) (encPair encBits encBits) encBool := by have hn : ComputableTidilyInPolyTime (fun p : List Bool × List Bool => p.1.length) (encPair encBits encBits) encUnary := diff --git a/Complexity/Computability/Complexity/Classes/PH/KarpLipton.lean b/Complexity/Computability/Complexity/Classes/PH/KarpLipton.lean index d9769ec68..0f7c4a223 100644 --- a/Complexity/Computability/Complexity/Classes/PH/KarpLipton.lean +++ b/Complexity/Computability/Complexity/Classes/PH/KarpLipton.lean @@ -95,7 +95,7 @@ section Family variable {N s : ℕ} {C : ∀ m, Circuit signature m 1} -theorem length_familyAdvice_block (hs : ∀ m ≤ N, (C m).size ≤ s) {m : ℕ} (hm : m ≤ N) : +private theorem length_familyAdvice_block (hs : ∀ m ≤ N, (C m).size ≤ s) {m : ℕ} (hm : m ≤ N) : (certificate m s (C m).code.1 ((C m).outputs 0).toNat ++ List.replicate (certLength N s - certLength m s) false).length = certLength N s := by rw [List.length_append, length_certificate_code _ (hs m hm), List.length_replicate, @@ -110,7 +110,7 @@ theorem length_familyAdvice (hs : ∀ m ≤ N, (C m).size ≤ s) : List.length_range, List.sum_replicate, smul_eq_mul] /-- Block `m` of the advice string of a family starts with the certificate of `C m`. -/ -theorem drop_familyAdvice (hs : ∀ m ≤ N, (C m).size ≤ s) {m : ℕ} (hm : m ≤ N) : +private theorem drop_familyAdvice (hs : ∀ m ≤ N, (C m).size ≤ s) {m : ℕ} (hm : m ≤ N) : ∃ rest, (familyAdvice N s C).drop (m * certLength N s) = certificate m s (C m).code.1 ((C m).outputs 0).toNat ++ rest := by obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le hm @@ -172,21 +172,21 @@ namespace KarpLipton `w₁` has `P (enc a).length` bits, it runs the self-reduction of `f (a, u)` with the circuits read from the advice string `w₁` (with at most `S (enc a).length` gates, in blocks of `W (enc a).length` bits), and checks the assignment it finds. -/ -def verifier (enc : α ↪ List Bool) (f : α × List Bool → CNF ℕ) (S W P : Polynomial ℕ) +private def verifier (enc : α ↪ List Bool) (f : α × List Bool → CNF ℕ) (S W P : Polynomial ℕ) (x : α × List Bool) : Bool := SAT.verifier (f (x.1, x.2.drop (P.eval (enc x.1).length)), SAT.search (fun ψ => evalAdvice (S.eval (enc x.1).length) (W.eval (enc x.1).length) (x.2.take (P.eval (enc x.1).length)) (encCNF ψ)) (f (x.1, x.2.drop (P.eval (enc x.1).length)))) -theorem verifier_append {f : α × List Bool → CNF ℕ} {S W P : Polynomial ℕ} (a : α) +private theorem verifier_append {f : α × List Bool → CNF ℕ} {S W P : Polynomial ℕ} (a : α) {w₁ : List Bool} (hw₁ : w₁.length = P.eval (enc a).length) (u : List Bool) : verifier enc f S W P (a, w₁ ++ u) = SAT.verifier (f (a, u), SAT.search (fun ψ => evalAdvice (S.eval (enc a).length) (W.eval (enc a).length) w₁ (encCNF ψ)) (f (a, u))) := by rw [verifier, ← hw₁, List.drop_left, List.take_left] -theorem computableTidilyInPolyTime_verifier {f : α × List Bool → CNF ℕ} +private theorem computableTidilyInPolyTime_verifier {f : α × List Bool → CNF ℕ} (hf : ComputableTidilyInPolyTime f (encPair enc encBits) encCNF) (S W P : Polynomial ℕ) : ComputableTidilyInPolyTime (verifier enc f S W P) (encPair enc encBits) encBool := by have hn : ComputableTidilyInPolyTime (fun x : α × List Bool => (enc x.1).length) diff --git a/Complexity/Computability/Complexity/Classes/PH/SipserLautemann.lean b/Complexity/Computability/Complexity/Classes/PH/SipserLautemann.lean index eada23fc3..bede5cfba 100644 --- a/Complexity/Computability/Complexity/Classes/PH/SipserLautemann.lean +++ b/Complexity/Computability/Complexity/Classes/PH/SipserLautemann.lean @@ -356,7 +356,7 @@ theorem verifier_polyTime {enc : α ↪ List Bool} {p : Polynomial ℕ} {V : α /-- On a combined certificate `u ++ r` with `u.length = witnessLen m`, `trialSeed` reconstructs the `j`-th block of the shifted seed `listToSeed m r + listToShifts m u i`. -/ -theorem trialSeed_append {m : ℕ} {u r : List Bool} (hu : u.length = witnessLen m) +private theorem trialSeed_append {m : ℕ} {u r : List Bool} (hu : u.length = witnessLen m) (i : Fin (shifts m)) (j : Fin (runs m)) : trialSeed m (u ++ r) i.1 j.1 = List.ofFn ((listToSeed m r + listToShifts m u i) j) := by apply List.ext_getElem (by simp [trialSeed]) diff --git a/Complexity/Computability/Complexity/Classes/SPP/FewP.lean b/Complexity/Computability/Complexity/Classes/SPP/FewP.lean index 2a55f49ed..0a0dbf2e6 100644 --- a/Complexity/Computability/Complexity/Classes/SPP/FewP.lean +++ b/Complexity/Computability/Complexity/Classes/SPP/FewP.lean @@ -310,7 +310,7 @@ def verifier (enc : α ↪ List Bool) (p q : Polynomial ℕ) (V : α × List Boo (step fun c => V (x.1, c)) init) /-- The encoding of the states of a scan. -/ -abbrev encState : State ↪ List Bool := +private abbrev encState : State ↪ List Bool := encPair encBool (encPair encBool (encPair encBool (encPair encBool encBits))) /-- A slot grows the encoded state by at most its length. -/ diff --git a/Complexity/Computability/Complexity/Classes/SharpP/Aggregation.lean b/Complexity/Computability/Complexity/Classes/SharpP/Aggregation.lean index 8b053ef38..d9e02214d 100644 --- a/Complexity/Computability/Complexity/Classes/SharpP/Aggregation.lean +++ b/Complexity/Computability/Complexity/Classes/SharpP/Aggregation.lean @@ -81,7 +81,7 @@ namespace SignedProduct abbrev State := Bool × Bool /-- Difference of the two acceptance flags. -/ -def sign (s : State) : ℤ := (if s.1 then 1 else 0) - (if s.2 then 1 else 0) +private def sign (s : State) : ℤ := (if s.1 then 1 else 0) - (if s.2 then 1 else 0) /-- Multiplication of signed Boolean flags; overlap cancels in their difference. -/ def mul (s t : State) : State := @@ -107,7 +107,7 @@ def verifier (r k : α → ℕ) (V W : α × List Bool → Bool) (b : Bool) if b then s.2 else s.1 /-- The two product verifiers run in polynomial time for unary row count and width. -/ -theorem polyTime_verifier {r k : α → ℕ} {V W : α × List Bool → Bool} +private theorem polyTime_verifier {r k : α → ℕ} {V W : α × List Bool → Bool} (hr : ComputableTidilyInPolyTime r enc encUnary) (hk : ComputableTidilyInPolyTime k enc encUnary) (hV : ComputableTidilyInPolyTime V (encPair enc encBits) encBool) diff --git a/Complexity/Computability/Complexity/Classes/SharpP/Products.lean b/Complexity/Computability/Complexity/Classes/SharpP/Products.lean index 5a86c3f5a..dd155b367 100644 --- a/Complexity/Computability/Complexity/Classes/SharpP/Products.lean +++ b/Complexity/Computability/Complexity/Classes/SharpP/Products.lean @@ -137,7 +137,7 @@ theorem prod_sub_mul_eq_sum {n : ℕ} (f g : Fin n → ℤ) (c : ℤ) : /-- Expanding a product of differences over Boolean choices: each term selects `g i` where `w i` is true and `f i` where `w i` is false, weighted by `(-1)` to the number of true bits. -/ -theorem prod_sub_eq_sum {n : ℕ} (f g : Fin n → ℤ) : +private theorem prod_sub_eq_sum {n : ℕ} (f g : Fin n → ℤ) : (∏ i, (f i - g i)) = ∑ w : Fin n → Bool, (-1 : ℤ) ^ (List.ofFn w).countP id * ∏ i, if w i then g i else f i := by simpa using prod_sub_mul_eq_sum f g 1 diff --git a/Complexity/Computability/Complexity/Classes/Space/GeneralizedGeography/Membership.lean b/Complexity/Computability/Complexity/Classes/Space/GeneralizedGeography/Membership.lean index 406faf633..29d66ef3f 100644 --- a/Complexity/Computability/Complexity/Classes/Space/GeneralizedGeography/Membership.lean +++ b/Complexity/Computability/Complexity/Classes/Space/GeneralizedGeography/Membership.lean @@ -89,7 +89,7 @@ theorem length_moverBits (B : ℕ) (first : Bool) (z : List Bool) : (moverBits B first z).length = B := by simp [moverBits] -theorem moverBits_cons_cons (B : ℕ) (first b c : Bool) (z : List Bool) : +private theorem moverBits_cons_cons (B : ℕ) (first b c : Bool) (z : List Bool) : moverBits (B + 1) first (b :: c :: z) = (if first then b else c) :: moverBits B first z := by simp only [moverBits, List.range_succ_eq_map, List.map_cons, List.map_map] congr 1 @@ -100,7 +100,7 @@ theorem moverBits_cons_cons (B : ℕ) (first b c : Bool) (z : List Bool) : ring, List.getD_cons_succ, List.getD_cons_succ] /-- Only the first block is read. -/ -theorem moverBits_take (B : ℕ) (first : Bool) (z : List Bool) : +private theorem moverBits_take (B : ℕ) (first : Bool) (z : List Bool) : moverBits B first (z.take (2 * B)) = moverBits B first z := by refine List.map_congr_left fun j hj => ?_ rw [List.mem_range] at hj @@ -180,14 +180,14 @@ theorem alternation_moverBits_false {ns : List ℕ} : def choice (bits : List Bool) : ℕ := bits.idxOf true /-- The bits naming the arc of index `i` among `B`. -/ -def indicator (B i : ℕ) : List Bool := +private def indicator (B i : ℕ) : List Bool := List.replicate i false ++ true :: List.replicate (B - i - 1) false -theorem length_indicator {B i : ℕ} (h : i < B) : (indicator B i).length = B := by +private theorem length_indicator {B i : ℕ} (h : i < B) : (indicator B i).length = B := by simp only [indicator, List.length_append, List.length_replicate, List.length_cons] omega -theorem choice_indicator (B i : ℕ) : choice (indicator B i) = i := by +private theorem choice_indicator (B i : ℕ) : choice (indicator B i) = i := by rw [choice, indicator, List.idxOf_append_of_notMem (by simp), List.idxOf_cons_self] simp @@ -200,7 +200,7 @@ def legal (G : Graph) (vis : List ℕ) (v i : ℕ) : Bool := decide (i < G.2.length) && decide ((arc G i).1 = v) && decide ((arc G i).2 ∈ G.1) && !decide ((arc G i).2 ∈ vis) -theorem arc_eq {G : Graph} {i : ℕ} (hi : i < G.2.length) : arc G i = G.2[i] := +private theorem arc_eq {G : Graph} {i : ℕ} (hi : i < G.2.length) : arc G i = G.2[i] := List.getD_eq_getElem _ _ hi theorem legal_eq_true_iff {G : Graph} {vis : List ℕ} {v i : ℕ} : @@ -274,7 +274,7 @@ def step (G : Graph) (B : ℕ) (st : Play) (block : List Bool) : Play := def blocks (B R : ℕ) (z : List Bool) : List (List Bool) := (List.range R).map fun r => (z.drop (2 * B * r)).take (2 * B) -theorem blocks_succ (B R : ℕ) (z : List Bool) : +private theorem blocks_succ (B R : ℕ) (z : List Bool) : blocks B (R + 1) z = z.take (2 * B) :: blocks B R (z.drop (2 * B)) := by simp only [blocks, List.range_succ_eq_map, List.map_cons, List.map_map, Nat.mul_zero, List.drop_zero] @@ -285,7 +285,7 @@ theorem blocks_succ (B R : ℕ) (z : List Bool) : ring /-- The blocks only read their moves. -/ -theorem blocks_take (B R : ℕ) (z : List Bool) : +private theorem blocks_take (B R : ℕ) (z : List Bool) : blocks B R (z.take (2 * B * R)) = blocks B R z := by refine List.map_congr_left fun r hr => ?_ rw [List.mem_range] at hr @@ -297,7 +297,7 @@ theorem blocks_take (B R : ℕ) (z : List Bool) : omega /-- A play that is over stays over. -/ -theorem foldl_step_some (G : Graph) (B : ℕ) (b : Bool) (rest : Bool × List ℕ × ℕ) : +private theorem foldl_step_some (G : Graph) (B : ℕ) (b : Bool) (rest : Bool × List ℕ × ℕ) : ∀ bs : List (List Bool), bs.foldl (step G B) (some b, rest) = (some b, rest) | [] => rfl | _ :: bs => by @@ -389,7 +389,7 @@ def verifier (x : (Graph × ℕ) × List Bool) : Bool := /-- The arcs and the declared vertex entries of a graph are no more than the length of the encoded instance. -/ -theorem length_le_length_encode (x : Graph × ℕ) : +private theorem length_le_length_encode (x : Graph × ℕ) : x.1.2.length ≤ (encPair encGraph encNat x).length ∧ x.1.1.length ≤ (encPair encGraph encNat x).length := by have h₁ := length_le_length_encList (encPair encNat encNat) x.1.2 @@ -444,7 +444,7 @@ theorem computableTidilyInPolyTime_moverBits {B : γ → ℕ} {first : γ → Bo fun_prop /-- A move is polynomial-time. -/ -theorem computableTidilyInPolyTime_next : +private theorem computableTidilyInPolyTime_next : ComputableTidilyInPolyTime (fun p : (Graph × Play) × List Bool => next p.1.1 p.1.2.2.1 p.1.2.2.2.1 p.1.2.2.2.2 p.2) (encPair (encPair encGraph encPlay) (encList encBool)) encPlay := by @@ -490,7 +490,7 @@ theorem computableTidilyInPolyTime_next : (((optionSome encBool).comp (bool_not.comp hfirst)).prod (hfirst.prod (hvis.prod hv))) /-- A target of an arc is no longer in binary than the encoded graph. -/ -theorem length_encNat_le_of_mem {G : Graph} {e : ℕ × ℕ} (he : e ∈ G.2) : +private theorem length_encNat_le_of_mem {G : Graph} {e : ℕ × ℕ} (he : e ∈ G.2) : (encNat e.2).length ≤ (encGraph G).length := by have h₁ := sum_length_le_length_encList (encPair encNat encNat) G.2 have h₂ := List.le_sum_of_mem (List.mem_map_of_mem (f := fun a => diff --git a/Complexity/Computability/Complexity/Classes/Space/GeneralizedGeography/Reduction.lean b/Complexity/Computability/Complexity/Classes/Space/GeneralizedGeography/Reduction.lean index fd0b9aca4..f93bdd276 100644 --- a/Complexity/Computability/Complexity/Classes/Space/GeneralizedGeography/Reduction.lean +++ b/Complexity/Computability/Complexity/Classes/Space/GeneralizedGeography/Reduction.lean @@ -231,24 +231,24 @@ def visOf (z : List Bool) : List ℕ := (List.range (z.length + 1)).map topNode ++ (List.range z.length).map bottomNode ++ (List.range z.length).map fun j => valueNode j (z.getD j false) -theorem topNode_mem_visOf : topNode j ∈ visOf z ↔ j ≤ z.length := by +private theorem topNode_mem_visOf : topNode j ∈ visOf z ↔ j ≤ z.length := by simp only [visOf, List.mem_append, List.mem_map, List.mem_range] simp [topNode, bottomNode, valueNode, Nat.pair_eq_pair] -theorem bottomNode_mem_visOf : bottomNode j ∈ visOf z ↔ j < z.length := by +private theorem bottomNode_mem_visOf : bottomNode j ∈ visOf z ↔ j < z.length := by simp only [visOf, List.mem_append, List.mem_map, List.mem_range] simp [topNode, bottomNode, valueNode, Nat.pair_eq_pair] -theorem chooserNode_notMem_visOf : chooserNode ∉ visOf z := by +private theorem chooserNode_notMem_visOf : chooserNode ∉ visOf z := by simp only [visOf, List.mem_append, List.mem_map, List.mem_range] simp [topNode, bottomNode, valueNode, chooserNode, Nat.pair_eq_pair] -theorem clauseNode_notMem_visOf {i : ℕ} : clauseNode i ∉ visOf z := by +private theorem clauseNode_notMem_visOf {i : ℕ} : clauseNode i ∉ visOf z := by simp only [visOf, List.mem_append, List.mem_map, List.mem_range] simp [topNode, bottomNode, valueNode, clauseNode, Nat.pair_eq_pair] /-- Every vertex of `visOf z` is a top, a bottom or a value node. -/ -theorem mem_visOf {u : ℕ} : u ∈ visOf z ↔ +private theorem mem_visOf {u : ℕ} : u ∈ visOf z ↔ (∃ j ≤ z.length, u = topNode j) ∨ (∃ j < z.length, u = bottomNode j) ∨ ∃ j < z.length, u = valueNode j (z.getD j false) := by simp only [visOf, List.mem_append, List.mem_map, List.mem_range, Nat.lt_succ_iff, or_assoc] @@ -260,7 +260,7 @@ theorem valueNode_inj {i : ℕ} {b c : Bool} : valueNode j b = valueNode i c ↔ simp only [valueNode, Nat.pair_eq_pair, true_and] cases b <;> cases c <;> simp -theorem valueNode_mem_visOf {b : Bool} : +private theorem valueNode_mem_visOf {b : Bool} : valueNode j b ∈ visOf z ↔ j < z.length ∧ b = z.getD j false := by rw [mem_visOf] constructor @@ -273,7 +273,7 @@ theorem valueNode_mem_visOf {b : Bool} : exact Or.inr (Or.inr ⟨j, hj, rfl⟩) /-- Crossing a diamond visits its value node, its bottom and the next top. -/ -theorem mem_visOf_append {b : Bool} {u : ℕ} : +private theorem mem_visOf_append {b : Bool} {u : ℕ} : u ∈ visOf (z ++ [b]) ↔ u ∈ topNode (z.length + 1) :: bottomNode z.length :: valueNode z.length b :: visOf z := by have hget (j : ℕ) (hj : j < z.length + 1) : @@ -320,13 +320,13 @@ theorem geographyWins_formulaGraph_iff {vis : List ℕ} {v : ℕ} : refine exists_congr fun w => ⟨fun ⟨h, _, h'⟩ => ⟨h, h'⟩, fun ⟨h, h'⟩ => ⟨h, ?_, h'⟩⟩ exact List.mem_cons_of_mem _ (List.mem_map_of_mem (f := Prod.snd) h) -theorem lastIdx_lt {x : ℕ} (hx : x ∈ xs) : lastIdx xs x < xs.length := by +private theorem lastIdx_lt {x : ℕ} (hx : x ∈ xs) : lastIdx xs x < xs.length := by have := List.length_pos_of_mem hx unfold lastIdx omega /-- From a value node whose bottom is visited, the player to move loses. -/ -theorem not_geographyWins_valueNode {vis : List ℕ} {j : ℕ} {c : Bool} (hj : j < xs.length) +private theorem not_geographyWins_valueNode {vis : List ℕ} {j : ℕ} {c : Bool} (hj : j < xs.length) (hvis : bottomNode j ∈ vis) : ¬(formulaGraph xs ψ).GeographyWins vis (valueNode j c) := by rw [geographyWins_formulaGraph_iff] rintro ⟨w, hw, hwvis, -⟩ @@ -335,7 +335,7 @@ theorem not_geographyWins_valueNode {vis : List ℕ} {j : ℕ} {c : Bool} (hj : /-- From the node of a clause, with every bottom visited, the first player wins exactly when the value node of the negation of some literal of the clause is unvisited. -/ -theorem geographyWins_clauseNode {vis : List ℕ} {i : ℕ} (hi : i < ψ.length) +private theorem geographyWins_clauseNode {vis : List ℕ} {i : ℕ} (hi : i < ψ.length) (hvis : ∀ j < xs.length, bottomNode j ∈ vis) : (formulaGraph xs ψ).GeographyWins vis (clauseNode i) ↔ ∃ l ∈ ψ[i], l.1 ∈ xs ∧ valueNode (lastIdx xs l.1) (!l.2) ∉ vis := by @@ -432,7 +432,8 @@ theorem geographyWins_topNode_lt {z : List Bool} (hj : z.length < xs.length) : /-- **The game on the graph of a formula**, from the top of diamond `j` after the values `z` have been chosen: the player to move, the first player when `j` is even, wins exactly when the quantifiers over the remaining `k` variables, starting with `∃` when `j` is even, hold. -/ -theorem geographyWins_topNode (heven : Even xs.length) (hvars : ∀ c ∈ ψ, ∀ l ∈ c, l.1 ∈ xs) : +private theorem geographyWins_topNode (heven : Even xs.length) + (hvars : ∀ c ∈ ψ, ∀ l ∈ c, l.1 ∈ xs) : ∀ (k : ℕ) (z : List Bool), z.length + k = xs.length → ((formulaGraph xs ψ).GeographyWins (visOf z) (topNode z.length) ↔ ((z.length % 2 == 0) = true ↔ Alternation (z.length % 2 == 0) (List.replicate k 1) diff --git a/Complexity/Computability/Complexity/Classes/Space/TQBF/Evaluation.lean b/Complexity/Computability/Complexity/Classes/Space/TQBF/Evaluation.lean index da0731b49..acebd0298 100644 --- a/Complexity/Computability/Complexity/Classes/Space/TQBF/Evaluation.lean +++ b/Complexity/Computability/Complexity/Classes/Space/TQBF/Evaluation.lean @@ -158,12 +158,12 @@ def callSteps : QBF ℕ → ℕ /-! ### The assignment of a stack -/ /-- A frame that is not a quantifier does not change the values of the stack. -/ -theorem lookup_cons_of_binds_eq_false {f : Frame} (h : ∀ v, f.binds v = false) +private theorem lookup_cons_of_binds_eq_false {f : Frame} (h : ∀ v, f.binds v = false) (stack : List Frame) (v : ℕ) : lookup (f :: stack) v = lookup stack v := by simp [lookup, h v] /-- A quantifier frame over `x` gives `x` its value. -/ -theorem lookup_cons_quant {f : Frame} {k : QBF.Kind} {x : ℕ} (hk : k = .ex ∨ k = .all) +private theorem lookup_cons_quant {f : Frame} {k : QBF.Kind} {x : ℕ} (hk : k = .ex ∨ k = .all) (hf : f.token = (k, x)) (stack : List Frame) (v : ℕ) : lookup (f :: stack) v = if v = x then some f.first.isSome else lookup stack v := by have hb : f.binds v = true ↔ v = x := by @@ -177,14 +177,14 @@ theorem lookup_cons_quant {f : Frame} {k : QBF.Kind} {x : ℕ} (hk : k = .ex ∨ simp [hv, lookup] /-- A frame that is not a quantifier does not change the assignment. -/ -theorem assignment_cons_of_binds_eq_false {f : Frame} (h : ∀ v, f.binds v = false) +private theorem assignment_cons_of_binds_eq_false {f : Frame} (h : ∀ v, f.binds v = false) (stack : List Frame) : assignment (f :: stack) = assignment stack := by funext v simp only [assignment, lookup_cons_of_binds_eq_false h] /-- A quantifier frame over `x` sets `x` to `false` during its first pass and to `true` during its second. -/ -theorem assignment_cons_quant {f : Frame} {k : QBF.Kind} {x : ℕ} (hk : k = .ex ∨ k = .all) +private theorem assignment_cons_quant {f : Frame} {k : QBF.Kind} {x : ℕ} (hk : k = .ex ∨ k = .all) (hf : f.token = (k, x)) (stack : List Frame) : assignment (f :: stack) = Function.update (assignment stack) x f.first.isSome := by funext v @@ -192,13 +192,13 @@ theorem assignment_cons_quant {f : Frame} {k : QBF.Kind} {x : ℕ} (hk : k = .ex split_ifs <;> rfl /-- A frame that is not a quantifier does not change closedness. -/ -theorem closedIn_cons_of_binds_eq_false {f : Frame} (h : ∀ v, f.binds v = false) +private theorem closedIn_cons_of_binds_eq_false {f : Frame} (h : ∀ v, f.binds v = false) (stack : List Frame) (φ : QBF ℕ) : closedIn (f :: stack) φ = closedIn stack φ := by simp only [closedIn, lookup_cons_of_binds_eq_false h] /-- Under a quantifier frame over `x`, a formula is closed exactly when quantifying it over `x` gives a formula closed relative to the rest of the stack. -/ -theorem closedIn_cons_quant {f : Frame} {k : QBF.Kind} {x : ℕ} (hk : k = .ex ∨ k = .all) +private theorem closedIn_cons_quant {f : Frame} {k : QBF.Kind} {x : ℕ} (hk : k = .ex ∨ k = .all) (hf : f.token = (k, x)) (stack : List Frame) (φ : QBF ℕ) : closedIn (f :: stack) φ = closedIn stack (.ex x φ) := by simp only [closedIn, lookup_cons_quant hk hf, QBF.freeVars_ex] @@ -210,7 +210,7 @@ theorem closedIn_cons_quant {f : Frame} {k : QBF.Kind} {x : ℕ} (hk : k = .ex · simpa [hvx] using h v (Finset.mem_erase.mpr ⟨hvx, hv⟩) /-- Closedness of a variable. -/ -theorem closedIn_var (stack : List Frame) (v : ℕ) : +private theorem closedIn_var (stack : List Frame) (v : ℕ) : closedIn stack (.var v) = (lookup stack v).isSome := by simp [closedIn] @@ -219,24 +219,24 @@ theorem closedIn_not (stack : List Frame) (φ : QBF ℕ) : closedIn stack φ.not = closedIn stack φ := rfl /-- Closedness of a conjunction. -/ -theorem closedIn_and (stack : List Frame) (φ ψ : QBF ℕ) : +private theorem closedIn_and (stack : List Frame) (φ ψ : QBF ℕ) : closedIn stack (φ.and ψ) = (closedIn stack φ && closedIn stack ψ) := by simp only [closedIn, QBF.freeVars_and, Finset.mem_union, or_imp, forall_and, Bool.decide_and] /-- Closedness of a disjunction. -/ -theorem closedIn_or (stack : List Frame) (φ ψ : QBF ℕ) : +private theorem closedIn_or (stack : List Frame) (φ ψ : QBF ℕ) : closedIn stack (φ.or ψ) = (closedIn stack φ && closedIn stack ψ) := by simp only [closedIn, QBF.freeVars_or, Finset.mem_union, or_imp, forall_and, Bool.decide_and] /-- A universal quantifier and an existential one have the same free variables. -/ -theorem closedIn_all (stack : List Frame) (x : ℕ) (φ : QBF ℕ) : +private theorem closedIn_all (stack : List Frame) (x : ℕ) (φ : QBF ℕ) : closedIn stack (.all x φ) = closedIn stack (.ex x φ) := rfl /-- The empty stack gives every variable the value `false`. -/ -theorem assignment_nil : assignment [] = fun _ => false := rfl +private theorem assignment_nil : assignment [] = fun _ => false := rfl /-- Relative to the empty stack, closedness is closedness. -/ -theorem closedIn_nil (φ : QBF ℕ) : closedIn [] φ = decide φ.Closed := by +private theorem closedIn_nil (φ : QBF ℕ) : closedIn [] φ = decide φ.Closed := by simp only [closedIn, lookup, List.find?_nil, Option.map_none, Option.isSome_none, Bool.false_eq_true, imp_false, QBF.Closed] exact Bool.decide_congr ⟨fun h => Finset.eq_empty_of_forall_notMem h, @@ -315,12 +315,12 @@ theorem exists_iterate_step_call (φ : QBF ℕ) (input : List (QBF.Kind × ℕ)) simp [step, closedIn_all] /-- An empty stack holding a value is a fixed point. -/ -theorem iterate_step_done (input : List (QBF.Kind × ℕ)) (b ok : Bool) (n : ℕ) : +private theorem iterate_step_done (input : List (QBF.Kind × ℕ)) (b ok : Bool) (n : ℕ) : step^[n] ⟨input, [], some b, ok⟩ = ⟨input, [], some b, ok⟩ := Function.iterate_fixed rfl n /-- The number of steps of a call is less than `4` to the number of tokens. -/ -theorem callSteps_lt (φ : QBF ℕ) : callSteps φ < 4 ^ φ.tokens.length := by +private theorem callSteps_lt (φ : QBF ℕ) : callSteps φ < 4 ^ φ.tokens.length := by induction φ with | var v => simp [callSteps, QBF.tokens] | top => simp [callSteps, QBF.tokens] @@ -397,7 +397,7 @@ theorem Nested.mono {n : ℕ} : ∀ {r r' : ℕ} {stack : List Frame}, Nested n | _, _, _ :: _, h, hr => ⟨le_trans hr h.1, h.2⟩ /-- A nested stack holds at most `n - r` frames. -/ -theorem Nested.length_le {n : ℕ} : ∀ {r : ℕ} {stack : List Frame}, Nested n r stack → +private theorem Nested.length_le {n : ℕ} : ∀ {r : ℕ} {stack : List Frame}, Nested n r stack → r + stack.length ≤ n | _, [], h => h | _, _ :: _, h => by @@ -418,11 +418,11 @@ structure Good (φ : QBF ℕ) (s : State) : Prop where nested : Nested φ.tokens.length s.input.length s.stack /-- The initial state satisfies the invariant. -/ -theorem good_init (φ : QBF ℕ) : Good φ (init φ) := +private theorem good_init (φ : QBF ℕ) : Good φ (init φ) := ⟨List.suffix_refl _, fun _ hf => by simp [init] at hf, le_refl _⟩ /-- The step preserves the invariant. -/ -theorem Good.step {φ : QBF ℕ} {s : State} (h : Good φ s) : Good φ (step s) := by +private theorem Good.step {φ : QBF ℕ} {s : State} (h : Good φ s) : Good φ (step s) := by obtain ⟨input, stack, value, ok⟩ := s obtain ⟨hin, hframes, hnest⟩ := h dsimp only at hin hframes hnest diff --git a/Complexity/Computability/Complexity/Classes/Space/TQBF/Formula.lean b/Complexity/Computability/Complexity/Classes/Space/TQBF/Formula.lean index d79702761..bba134dad 100644 --- a/Complexity/Computability/Complexity/Classes/Space/TQBF/Formula.lean +++ b/Complexity/Computability/Complexity/Classes/Space/TQBF/Formula.lean @@ -196,7 +196,7 @@ theorem freeVars_exs (vs : List V) (φ : QBF V) : simp only [Finset.mem_erase, Finset.mem_sdiff, Finset.mem_insert] tauto -theorem freeVars_alls (vs : List V) (φ : QBF V) : +private theorem freeVars_alls (vs : List V) (φ : QBF V) : (alls vs φ).freeVars = φ.freeVars \ vs.toFinset := by induction vs with | nil => simp [alls] @@ -260,7 +260,7 @@ theorem tokens_conj (l : List (QBF ℕ)) : | nil => rfl | cons φ l ih => simpa [conj, tokens] using ih -theorem tokens_imp (φ ψ : QBF ℕ) : +private theorem tokens_imp (φ ψ : QBF ℕ) : (imp φ ψ).tokens = (Kind.or, 0) :: (Kind.not, 0) :: (φ.tokens ++ ψ.tokens) := rfl theorem tokens_iff (φ ψ : QBF ℕ) : (iff φ ψ).tokens = @@ -314,7 +314,7 @@ theorem blockVar_inj {k k' i i' j j' : ℕ} (hk : k < 3) (hk' : k' < 3) simp only [blockVar, Nat.mul_left_cancel_iff two_pos, Nat.pair_eq_pair] at h omega -theorem blockVar_mem_blockVars {w k k' i i' j : ℕ} (hk : k < 3) (hk' : k' < 3) : +private theorem blockVar_mem_blockVars {w k k' i i' j : ℕ} (hk : k < 3) (hk' : k' < 3) : blockVar k i j ∈ blockVars w k' i' ↔ k = k' ∧ i = i' ∧ j < w := by simp only [blockVars, List.mem_map, List.mem_range] constructor @@ -324,7 +324,7 @@ theorem blockVar_mem_blockVars {w k k' i i' j : ℕ} (hk : k < 3) (hk' : k' < 3) · rintro ⟨rfl, rfl, hj⟩ exact ⟨j, hj, rfl⟩ -theorem nodup_blockVars (w kind i : ℕ) (hk : kind < 3) : (blockVars w kind i).Nodup := +private theorem nodup_blockVars (w kind i : ℕ) (hk : kind < 3) : (blockVars w kind i).Nodup := List.nodup_range.map fun _ _ h => (blockVar_inj hk hk h).2.2 /-- The source and target blocks of a level are disjoint. -/ @@ -338,13 +338,14 @@ theorem nodup_blockVars_append (w i : ℕ) : (blockVars w 0 i ++ blockVars w 1 i /-- Assignments agreeing outside a list of variables that misses a block hold the same word in it. -/ -theorem block_eq_of_agree {σ τ : ℕ → Bool} {vs : List ℕ} (h : ∀ x ∉ vs, τ x = σ x) {w k i : ℕ} +private theorem block_eq_of_agree {σ τ : ℕ → Bool} {vs : List ℕ} (h : ∀ x ∉ vs, τ x = σ x) + {w k i : ℕ} (hvs : ∀ j < w, blockVar k i j ∉ vs) : block τ w k i = block σ w k i := by simp only [block, blockVars, List.map_map] exact List.map_inj_left.mpr fun j hj => h _ (hvs j (List.mem_range.mp hj)) /-- Any values can be given to a list of distinct variables, keeping the others. -/ -theorem exists_agree_map_eq (σ : ℕ → Bool) {vs : List ℕ} (hvs : vs.Nodup) {bs : List Bool} +private theorem exists_agree_map_eq (σ : ℕ → Bool) {vs : List ℕ} (hvs : vs.Nodup) {bs : List Bool} (hbs : bs.length = vs.length) : ∃ τ, (∀ x ∉ vs, τ x = σ x) ∧ vs.map τ = bs := by classical refine ⟨fun x => if x ∈ vs then bs.getD (vs.idxOf x) false else σ x, fun x hx => by simp [hx], ?_⟩ @@ -354,7 +355,8 @@ theorem exists_agree_map_eq (σ : ℕ → Bool) {vs : List ℕ} (hvs : vs.Nodup) /-- Any two words of width `w` can be held by the source and target blocks of a level, keeping the other variables. -/ -theorem exists_agree_block (σ : ℕ → Bool) {w : ℕ} (i : ℕ) {u v : List Bool} (hu : u.length = w) +private theorem exists_agree_block (σ : ℕ → Bool) {w : ℕ} (i : ℕ) {u v : List Bool} + (hu : u.length = w) (hv : v.length = w) : ∃ τ, (∀ x ∉ blockVars w 0 i ++ blockVars w 1 i, τ x = σ x) ∧ block τ w 0 i = u ∧ block τ w 1 i = v := by obtain ⟨τ, hτ, h⟩ := exists_agree_map_eq σ (nodup_blockVars_append w i) (bs := u ++ v) @@ -364,7 +366,7 @@ theorem exists_agree_block (σ : ℕ → Bool) {w : ℕ} (i : ℕ) {u v : List B exact ⟨τ, hτ, h₁, h₂⟩ /-- Any word of width `w` can be held by a block, keeping the other variables. -/ -theorem exists_agree_block_one (σ : ℕ → Bool) {w k : ℕ} (hk : k < 3) (i : ℕ) {u : List Bool} +private theorem exists_agree_block_one (σ : ℕ → Bool) {w k : ℕ} (hk : k < 3) (i : ℕ) {u : List Bool} (hu : u.length = w) : ∃ τ, (∀ x ∉ blockVars w k i, τ x = σ x) ∧ block τ w k i = u := exists_agree_map_eq σ (nodup_blockVars w k i hk) (by simp [blockVars, hu]) @@ -384,7 +386,7 @@ theorem eval_eqBlock (σ : ℕ → Bool) (w k i k' i' : ℕ) : rw [Bool.eq_iff_iff, List.all_eq_true, decide_eq_true_iff, List.map_inj_left] simp -theorem eval_isBlock (σ : ℕ → Bool) {w : ℕ} (k i : ℕ) {u : List Bool} (hu : u.length = w) : +private theorem eval_isBlock (σ : ℕ → Bool) {w : ℕ} (k i : ℕ) {u : List Bool} (hu : u.length = w) : (isBlock w k i u).eval σ = decide (block σ w k i = u) := by have hu' : u = (List.range w).map fun j => u.getD j false := List.ext_getElem (by simp [hu]) fun j h₁ h₂ => by simp [List.getD_eq_getElem?_getD, h₁] @@ -402,7 +404,8 @@ theorem mem_freeVars_eqBlock {w k i k' i' x : ℕ} (hx : x ∈ (eqBlock w k i k' · exact .inl (List.mem_map.mpr ⟨j, List.mem_range.mpr hj, rfl⟩) · exact .inr (List.mem_map.mpr ⟨j, List.mem_range.mpr hj, rfl⟩) -theorem mem_freeVars_isBlock {w k i x : ℕ} {u : List Bool} (hx : x ∈ (isBlock w k i u).freeVars) : +private theorem mem_freeVars_isBlock {w k i x : ℕ} {u : List Bool} + (hx : x ∈ (isBlock w k i u).freeVars) : x ∈ blockVars w k i := by simp only [isBlock, QBF.mem_freeVars_conj, List.mem_map, List.mem_range] at hx obtain ⟨_, ⟨j, hj, rfl⟩, hx⟩ := hx @@ -493,7 +496,7 @@ theorem eval_midpoint {e : List Bool → List Bool → Bool} {w : ℕ} {base : Q /-- The free variables of the midpoint formula of level `i` lie in the source and target blocks of level `i`, as soon as those of the formula of level `0` lie in the blocks of level `0`. -/ -theorem mem_freeVars_midpoint {w : ℕ} {base : QBF ℕ} +private theorem mem_freeVars_midpoint {w : ℕ} {base : QBF ℕ} (hbase : ∀ x ∈ base.freeVars, x ∈ blockVars w 0 0 ∨ x ∈ blockVars w 1 0) (i : ℕ) : ∀ x ∈ (midpoint w base i).freeVars, x ∈ blockVars w 0 i ∨ x ∈ blockVars w 1 i := by induction i with @@ -569,7 +572,7 @@ def levelTokens (w i : ℕ) : List (QBF.Kind × ℕ) := (blockVars w 0 i ++ blockVars w 1 i).map (fun v => (.all, v)) ++ (halves w i).not.tokens.cons (.or, 0) -theorem tokens_midpoint_succ (w : ℕ) (base : QBF ℕ) (i : ℕ) : +private theorem tokens_midpoint_succ (w : ℕ) (base : QBF ℕ) (i : ℕ) : (midpoint w base (i + 1)).tokens = levelTokens w i ++ (midpoint w base i).tokens := by simp only [midpoint, QBF.tokens_exs, QBF.tokens_alls, QBF.tokens_imp, levelTokens, List.append_assoc, List.cons_append, QBF.tokens] diff --git a/Complexity/Computability/Complexity/Classes/Space/TQBF/Membership.lean b/Complexity/Computability/Complexity/Classes/Space/TQBF/Membership.lean index 5c06010e0..6b71729b7 100644 --- a/Complexity/Computability/Complexity/Classes/Space/TQBF/Membership.lean +++ b/Complexity/Computability/Complexity/Classes/Space/TQBF/Membership.lean @@ -152,16 +152,16 @@ open ComputableTidilyInPolyTime ((snd _ _).comp (snd _ _)).comp frameFields_pt /-- The next token, or `(top, 0)` when the input is empty. -/ -def State.head (s : State) : QBF.Kind × ℕ := s.input.headD (.top, 0) +private def State.head (s : State) : QBF.Kind × ℕ := s.input.headD (.top, 0) /-- The top frame, or a frame of `top` when the stack is empty. -/ -def State.top (s : State) : Frame := s.stack.headD ⟨(.top, 0), none, []⟩ +private def State.top (s : State) : Frame := s.stack.headD ⟨(.top, 0), none, []⟩ /-- The value being returned, or `false`. -/ -def State.ret (s : State) : Bool := s.value.getD false +private def State.ret (s : State) : Bool := s.value.getD false /-- A step reading a token of kind `k`. -/ -def readStep (k : QBF.Kind) (s : State) : State := +private def readStep (k : QBF.Kind) (s : State) : State := match k with | .var => ⟨s.input.tail, s.stack, some (assignment s.stack s.head.2), s.ok && (lookup s.stack s.head.2).isSome⟩ @@ -172,7 +172,7 @@ def readStep (k : QBF.Kind) (s : State) : State := /-- A step returning a value into a frame of kind `k`, during its second operand or pass when `second` holds. -/ -def retStep (k : QBF.Kind) (second : Bool) (s : State) : State := +private def retStep (k : QBF.Kind) (second : Bool) (s : State) : State := match k, second with | .not, _ => ⟨s.input, s.stack.tail, some !s.ret, s.ok⟩ | .and, false | .or, false => @@ -184,7 +184,7 @@ def retStep (k : QBF.Kind) (second : Bool) (s : State) : State := | .var, _ | .top, _ | .bot, _ => ⟨s.input, s.stack.tail, some s.ret, s.ok⟩ /-- The step as a case distinction on Boolean tests and finite tags. -/ -theorem step_eq (s : State) : step s = +private theorem step_eq (s : State) : step s = if s.value.isSome then (if s.stack.isEmpty then s else retStep s.top.token.1 s.top.first.isSome s) else if s.input.isEmpty then ⟨s.input, s.stack, some false, s.ok⟩ else readStep s.head.1 s := by @@ -198,12 +198,12 @@ theorem step_eq (s : State) : step s = · cases k <;> cases first <;> rfl /-- Whether a variable is bound, by a search of the stack. -/ -theorem isSome_lookup (stack : List Frame) (v : ℕ) : +private theorem isSome_lookup (stack : List Frame) (v : ℕ) : (lookup stack v).isSome = (stack.find? (Frame.binds v)).isSome := by simp [lookup] /-- The value of a variable, by a search of the stack. -/ -theorem assignment_eq (stack : List Frame) (v : ℕ) : +private theorem assignment_eq (stack : List Frame) (v : ℕ) : assignment stack v = (stack.find? (Frame.binds v)).elim false fun f => f.first.isSome := by simp only [assignment, lookup] cases stack.find? (Frame.binds v) <;> rfl @@ -295,7 +295,7 @@ private theorem length_encList_le_of_suffix {l l' : List (QBF.Kind × ℕ)} (h : /-- A frame storing a token of `φ` followed by a suffix of its tokens is no longer than the encoding of `φ`, up to its value. -/ -theorem length_encFrame_le {φ : QBF ℕ} {f : Frame} (h : f.token :: f.rest <:+ φ.tokens) : +private theorem length_encFrame_le {φ : QBF ℕ} {f : Frame} (h : f.token :: f.rest <:+ φ.tokens) : (encFrame f).length ≤ (encQBF φ).length + 5 := by have hs := length_encList_le_of_suffix h have hfirst : (encOption encBool f.first).length ≤ 2 := by cases f.first <;> simp [encOption] diff --git a/Complexity/Computability/Complexity/Classes/Space/TQBF/Prenex.lean b/Complexity/Computability/Complexity/Classes/Space/TQBF/Prenex.lean index 5239e15a0..68ba2a297 100644 --- a/Complexity/Computability/Complexity/Classes/Space/TQBF/Prenex.lean +++ b/Complexity/Computability/Complexity/Classes/Space/TQBF/Prenex.lean @@ -105,7 +105,7 @@ noncomputable def certLinkCNF (k : ℕ) (State : Type) [Fintype State] (w : ℕ) [[(tabVar (CookLevin.Var.cert (k := k) (State := State) j), false), (certVar w j, true)], [(tabVar (CookLevin.Var.cert (k := k) (State := State) j), true), (certVar w j, false)]] -theorem eval_certLinkCNF (w : ℕ) (σ : ℕ → Bool) : +private theorem eval_certLinkCNF (w : ℕ) (σ : ℕ → Bool) : CNF.eval σ (certLinkCNF k State w) = (certLinks k State w).eval σ := by rw [Bool.eq_iff_iff, certLinkCNF, CNF.eval_flatMap_eq_true_iff, certLinks, QBF.eval_conj, List.all_map, List.all_eq_true] @@ -119,14 +119,14 @@ theorem eval_certLinkCNF (w : ℕ) (σ : ℕ → Bool) : the midpoint block of level `0`. -/ def dummyVar : ℕ := blockVar 2 0 0 -theorem dummyVar_ne_tabVar (v : CookLevin.Var k State) : dummyVar ≠ tabVar v := by +private theorem dummyVar_ne_tabVar (v : CookLevin.Var k State) : dummyVar ≠ tabVar v := by intro h have h₁ := blockVar_mod_two 2 0 0 have h₂ := tabVar_mod_two v rw [dummyVar] at h omega -theorem dummyVar_ne_certVar (w j : ℕ) : dummyVar ≠ certVar w j := by +private theorem dummyVar_ne_certVar (w j : ℕ) : dummyVar ≠ certVar w j := by intro h unfold dummyVar certVar at h split_ifs at h @@ -143,7 +143,7 @@ as clauses, then the tableau. -/ noncomputable def prenexMatrix (tab : CNF (CookLevin.Var k State)) (w : ℕ) : CNF ℕ := certLinkCNF k State w ++ tab.relabel tabVar -theorem mem_vars_prenexMatrix {tab : CNF (CookLevin.Var k State)} {w x : ℕ} +private theorem mem_vars_prenexMatrix {tab : CNF (CookLevin.Var k State)} {w x : ℕ} (hx : x ∈ (prenexMatrix tab w).vars) : (∃ j < 2 * w, x = tabVar (CookLevin.Var.cert (k := k) (State := State) j) ∨ x = certVar w j) ∨ ∃ v ∈ tab.vars, x = tabVar v := by @@ -163,7 +163,7 @@ theorem mem_vars_prenexMatrix {tab : CNF (CookLevin.Var k State)} {w x : ℕ} obtain ⟨l', hl', rfl⟩ := hl exact Or.inr ⟨l'.1, List.mem_map.2 ⟨l', List.mem_flatten.2 ⟨c', hc', hl'⟩, rfl⟩, rfl⟩ -theorem dummyVar_notMem_freeVars (tab : CNF (CookLevin.Var k State)) (w : ℕ) : +private theorem dummyVar_notMem_freeVars (tab : CNF (CookLevin.Var k State)) (w : ℕ) : dummyVar ∉ (QBF.ofCNF (prenexMatrix tab w)).freeVars := by rw [QBF.mem_freeVars_ofCNF] intro h diff --git a/Complexity/Computability/Complexity/Classes/Space/TQBF/Reduction.lean b/Complexity/Computability/Complexity/Classes/Space/TQBF/Reduction.lean index a1c8bcffa..0668c192c 100644 --- a/Complexity/Computability/Complexity/Classes/Space/TQBF/Reduction.lean +++ b/Complexity/Computability/Complexity/Classes/Space/TQBF/Reduction.lean @@ -83,7 +83,7 @@ the first `w` bits, then the target block. -/ def certVar (w j : ℕ) : ℕ := if j < w then blockVar 0 0 j else blockVar 1 0 (j - w) /-- The certificate variables read the words held by the source and target blocks of level `0`. -/ -theorem map_certVar (σ : ℕ → Bool) (w : ℕ) : +private theorem map_certVar (σ : ℕ → Bool) (w : ℕ) : (List.range (2 * w)).map (fun j => σ (certVar w j)) = block σ w 0 0 ++ block σ w 1 0 := by have hlen : ((List.range (2 * w)).map fun j => σ (certVar w j)).length = (block σ w 0 0 ++ block σ w 1 0).length := by @@ -115,7 +115,7 @@ noncomputable def baseFormula (tab : CNF (CookLevin.Var k State)) (w : ℕ) : QB QBF.exs (baseVars tab w) (.and (certLinks k State w) (QBF.ofCNF (tab.relabel tabVar))) /-- Block variables are not quantified in the formula of level `0`. -/ -theorem certVar_notMem_baseVars (tab : CNF (CookLevin.Var k State)) (w j : ℕ) : +private theorem certVar_notMem_baseVars (tab : CNF (CookLevin.Var k State)) (w j : ℕ) : certVar w j ∉ baseVars tab w := by have h : certVar w j % 2 = 0 := by unfold certVar; split_ifs <;> exact blockVar_mod_two .. simp only [baseVars, List.mem_append, List.mem_map, not_or, not_exists, not_and] diff --git a/Complexity/Computability/Complexity/Classes/TFNP/SearchToDecision.lean b/Complexity/Computability/Complexity/Classes/TFNP/SearchToDecision.lean index 0ebc999dc..cfd5b24da 100644 --- a/Complexity/Computability/Complexity/Classes/TFNP/SearchToDecision.lean +++ b/Complexity/Computability/Complexity/Classes/TFNP/SearchToDecision.lean @@ -117,7 +117,7 @@ variable {V D : α × List Bool → Bool} (hV : ∀ a w, R a w ↔ V (a, w) = tr include hV /-- A solution is kept by the search. -/ -theorem foldl_prefixSearchStep_of_rel {a : α} {u : List Bool} (hu : R a u) (l : List Bool) : +private theorem foldl_prefixSearchStep_of_rel {a : α} {u : List Bool} (hu : R a u) (l : List Bool) : l.foldl (fun u _ => prefixSearchStep V D a u) u = u := by induction l with | nil => rfl @@ -129,7 +129,8 @@ include hD /-- A step from a word that some solution extends, but that is not a solution, adds one bit and keeps a solution extending the word. -/ -theorem prefixSearchStep_spec {a : α} {u : List Bool} (hu : ∃ v, R a (u ++ v)) (hnot : ¬R a u) : +private theorem prefixSearchStep_spec {a : α} {u : List Bool} (hu : ∃ v, R a (u ++ v)) + (hnot : ¬R a u) : (∃ v, R a (prefixSearchStep V D a u ++ v)) ∧ (prefixSearchStep V D a u).length = u.length + 1 := by have hVu : ¬V (a, u) = true := fun h => hnot ((hV a u).2 h) @@ -147,7 +148,7 @@ theorem prefixSearchStep_spec {a : α} {u : List Bool} (hu : ∃ v, R a (u ++ v) /-- The search through prefixes keeps a solution extending the word, and the word is a solution or has grown by one bit per step. -/ -theorem foldl_prefixSearchStep_spec {a : α} (l : List Bool) {u : List Bool} +private theorem foldl_prefixSearchStep_spec {a : α} (l : List Bool) {u : List Bool} (hu : ∃ v, R a (u ++ v)) : (∃ v, R a (l.foldl (fun u _ => prefixSearchStep V D a u) u ++ v)) ∧ (R a (l.foldl (fun u _ => prefixSearchStep V D a u) u) ∨ @@ -182,7 +183,7 @@ theorem rel_prefixSearchRun {n : α → ℕ} (hn : ∀ a w, R a w → w.length end Correctness /-- The search through prefixes is polynomial-time when `V`, `D` and the number of steps are. -/ -theorem computableTidilyInPolyTime_prefixSearchRun {V D : α × List Bool → Bool} {n : α → ℕ} +private theorem computableTidilyInPolyTime_prefixSearchRun {V D : α × List Bool → Bool} {n : α → ℕ} (hV : ComputableTidilyInPolyTime V (encPair enc encBits) encBool) (hD : ComputableTidilyInPolyTime D (encPair enc encBits) encBool) (hn : ComputableTidilyInPolyTime n enc encUnary) : diff --git a/Complexity/Computability/Complexity/Classes/TFNP/Subclasses.lean b/Complexity/Computability/Complexity/Classes/TFNP/Subclasses.lean index 8d517cb65..8f79c06fb 100644 --- a/Complexity/Computability/Complexity/Classes/TFNP/Subclasses.lean +++ b/Complexity/Computability/Complexity/Classes/TFNP/Subclasses.lean @@ -105,7 +105,7 @@ variable {α β : Type} /-! ### Polynomial-time bit-string and binary-number primitives -/ /-- `zeroVertex n = List.replicate n false` is computable in polynomial time from `n` in unary. -/ -theorem computableTidilyInPolyTime_zeroVertex : +private theorem computableTidilyInPolyTime_zeroVertex : ComputableTidilyInPolyTime zeroVertex encUnary encBits := by have heq (n : ℕ) : (List.replicate n true).foldl (fun acc _ => false :: acc) [] = zeroVertex n := by @@ -155,7 +155,7 @@ private theorem foldl_binaryBitsStep (w : List Bool) : /-- Decoding a most-significant-first bit string to its binary natural number (`encNat`) is polynomial-time. -/ -theorem computableTidilyInPolyTime_binaryValue : +private theorem computableTidilyInPolyTime_binaryValue : ComputableTidilyInPolyTime binaryValue encBits encNat := by have hstep : ComputableTidilyInPolyTime (fun p : List Bool × Bool => binaryBitsStep p.1 p.2) @@ -592,7 +592,7 @@ theorem PPA_subset_TFNP : PPA enc ⊆ TFNP enc := by exact ⟨hR, hred.isTotalSearch (isTotalSearch_leafRel hN₁_len hN₂_len)⟩ /-- Every directed end-of-line family search-reduces to its associated pigeonhole family. -/ -theorem endOfLineRel_searchReducible_pigeonRel {n : α → ℕ} {P S : α × List Bool → List Bool} +private theorem endOfLineRel_searchReducible_pigeonRel {n : α → ℕ} {P S : α × List Bool → List Bool} (hn : ComputableTidilyInPolyTime n enc encUnary) (hP : ComputableTidilyInPolyTime P (encPair enc encBits) encBits) (hS : ComputableTidilyInPolyTime S (encPair enc encBits) encBits) @@ -617,7 +617,7 @@ theorem PPAD_subset_PPP : PPAD enc ⊆ PPP enc := by /-- Every directed end-of-line family search-reduces to its associated bipartite undirected parity family. -/ -theorem endOfLineRel_searchReducible_leafRel {n : α → ℕ} {P S : α × List Bool → List Bool} +private theorem endOfLineRel_searchReducible_leafRel {n : α → ℕ} {P S : α × List Bool → List Bool} (hP_len : ∀ a u, u.length = n a → (P (a, u)).length = n a) (hS_len : ∀ a u, u.length = n a → (S (a, u)).length = n a) : SearchReducible enc enc (endOfLineRel n P S) @@ -677,7 +677,7 @@ def evalCircuitOutputs (code : CircuitCode) (u : List Bool) : List Bool := let vals := evalCode interpretation false u code.1 code.2.map (fun o => vals.getD o false) -theorem evalCircuitOutputs_eq_map (code : CircuitCode) (u : List Bool) : +private theorem evalCircuitOutputs_eq_map (code : CircuitCode) (u : List Bool) : evalCircuitOutputs code u = code.2.map fun o => (evalCode interpretation false u code.1).getD o false := rfl diff --git a/Complexity/Computability/Complexity/Classes/Toda/Counting.lean b/Complexity/Computability/Complexity/Classes/Toda/Counting.lean index db04336cd..4c47efbce 100644 --- a/Complexity/Computability/Complexity/Classes/Toda/Counting.lean +++ b/Complexity/Computability/Complexity/Classes/Toda/Counting.lean @@ -136,7 +136,7 @@ theorem sum_range_neg_two_pow_mul_choose_zmod (c K : ℕ) : and `2 ^ K - 2 ^ i` for odd `i`. -/ def parityCoeff (K i : ℕ) : ℕ := if Even i then 2 ^ i else 2 ^ K - 2 ^ i -theorem cast_parityCoeff {K i : ℕ} (hi : i ≤ K) : +private theorem cast_parityCoeff {K i : ℕ} (hi : i ≤ K) : (parityCoeff K i : ZMod (2 ^ K)) = (-2) ^ i := by have h2 : ((2 ^ K : ℕ) : ZMod (2 ^ K)) = 0 := ZMod.natCast_self _ unfold parityCoeff @@ -153,7 +153,7 @@ theorem cast_parityCoeff {K i : ℕ} (hi : i ≤ K) : /-- **One bit decides the majority.** If `H` is `G` modulo `2 ^ (R + 1)` and `G ≤ 2 ^ R`, then the bit `R + 1` of `2 H + (2 ^ R - 1)` says whether `2 G > 2 ^ R`. -/ -theorem testBit_two_mul_add_two_pow_sub_one {R G H : ℕ} (hG : G ≤ 2 ^ R) +private theorem testBit_two_mul_add_two_pow_sub_one {R G H : ℕ} (hG : G ≤ 2 ^ R) (hH : (H : ZMod (2 ^ (R + 1))) = G) : (2 * H + (2 ^ R - 1)).testBit (R + 1) = decide (2 ^ R < 2 * G) := by have hGlt : G < 2 ^ (R + 1) := by @@ -216,7 +216,7 @@ theorem card_filter_strictMono {β : Type*} [LinearOrder β] [Fintype β] (A : F exact ⟨(s.orderEmbOfFin hs.2).strictMono, fun i => hs.1 (orderEmbOfFin_mem s hs.2 i)⟩ /-- A tuple increasing at every step is strictly increasing. -/ -theorem strictMono_of_lt_succ {β : Type*} [Preorder β] {k : ℕ} {g : Fin k → β} +private theorem strictMono_of_lt_succ {β : Type*} [Preorder β] {k : ℕ} {g : Fin k → β} (h : ∀ (i : ℕ) (hi : i + 1 < k), g ⟨i, by omega⟩ < g ⟨i + 1, hi⟩) : StrictMono g := by cases k with | zero => exact fun i => i.elim0 @@ -246,7 +246,7 @@ theorem computableTidilyInPolyTime_subsetTest {γ : Type} {input : γ ↪ List B fun_prop /-- **The `k`-subset test counts `k`-element sets of accepted words**, for `k ≤ K`. -/ -theorem card_filter_subsetTest (acc : List Bool → Bool) {K k : ℕ} (Z : ℕ) (hk : k ≤ K) : +private theorem card_filter_subsetTest (acc : List Bool → Bool) {K k : ℕ} (Z : ℕ) (hk : k ≤ K) : (univ.filter fun zs : Fin (K * Z) → Bool => subsetTest acc K Z k (List.ofFn zs) = true).card = ((univ.filter fun z : Fin Z → Bool => acc (List.ofFn z) = true).card).choose k := by classical @@ -356,7 +356,7 @@ theorem computableTidilyInPolyTime_unaryTest {γ : Type} {input : γ ↪ List Bo /-- Summing over the words passing the unary test of length `K` sums over the sizes `1, …, K`. -/ -theorem sum_unaryTest (K : ℕ) (F : ℕ → ℕ) : +private theorem sum_unaryTest (K : ℕ) (F : ℕ → ℕ) : ∑ kb : Fin K → Bool, (if unaryTest K (List.ofFn kb) then F ((List.ofFn kb).count true) else 0) = ∑ i ∈ range K, F (i + 1) := by classical @@ -406,7 +406,7 @@ theorem computableTidilyInPolyTime_coeffTest {γ : Type} {input : γ ↪ List Bo fun_prop /-- The coefficient test for size `k` accepts `parityCoeff K (k - 1)` words. -/ -theorem card_filter_coeffTest {K k : ℕ} (hk : 1 ≤ k) (hkK : k ≤ K) : +private theorem card_filter_coeffTest {K k : ℕ} (hk : 1 ≤ k) (hkK : k ≤ K) : (univ.filter fun cb : Fin K → Bool => coeffTest K k (List.ofFn cb) = true).card = parityCoeff K (k - 1) := by classical diff --git a/Complexity/Computability/Complexity/Classes/Toda/Hierarchy.lean b/Complexity/Computability/Complexity/Classes/Toda/Hierarchy.lean index 837fe98ac..ebb3f1367 100644 --- a/Complexity/Computability/Complexity/Classes/Toda/Hierarchy.lean +++ b/Complexity/Computability/Complexity/Classes/Toda/Hierarchy.lean @@ -110,7 +110,7 @@ theorem congr (h : IsRandomParityRep enc ℓ e ρ ζ W P) rwa [hPQ a u hu])).trans (h a u hu) /-- A verifier right on every random string represents `P` with every error. -/ -theorem of_forall +private theorem of_forall (h : ∀ (a : α) (u : List Bool), u.length = ℓ.eval (enc a).length → ∀ r : Fin (ρ.eval (enc a).length) → Bool, Odd (acceptCount (fun x => W (x.1, u ++ List.ofFn r ++ x.2)) a (ζ.eval (enc a).length)) ↔ @@ -142,7 +142,8 @@ def notVerifier (enc : α ↪ List Bool) (ℓ ρ : Polynomial ℕ) (W : α × Li y.2)) (x.1, x.2.drop (ℓ.eval (enc x.1).length + ρ.eval (enc x.1).length)) -theorem computableTidilyInPolyTime_notVerifier (ℓ ρ : Polynomial ℕ) {W : α × List Bool → Bool} +private theorem computableTidilyInPolyTime_notVerifier (ℓ ρ : Polynomial ℕ) + {W : α × List Bool → Bool} (hW : ComputableTidilyInPolyTime W (encPair enc encBits) encBool) : ComputableTidilyInPolyTime (notVerifier enc ℓ ρ W) (encPair enc encBits) encBool := by unfold notVerifier succVerifier @@ -240,7 +241,7 @@ theorem computableTidilyInPolyTime_trialsVerifier {W : α × List Bool → Bool} unfold trialsVerifier fun_prop -theorem computableTidilyInPolyTime_existsVerifier (ℓ m ρ ζ e : Polynomial ℕ) +private theorem computableTidilyInPolyTime_existsVerifier (ℓ m ρ ζ e : Polynomial ℕ) {W : α × List Bool → Bool} (hW : ComputableTidilyInPolyTime W (encPair enc encBits) encBool) : ComputableTidilyInPolyTime (existsVerifier enc ℓ m ρ ζ e W) (encPair enc encBits) encBool := by unfold existsVerifier @@ -248,7 +249,7 @@ theorem computableTidilyInPolyTime_existsVerifier (ℓ m ρ ζ e : Polynomial /-- One trial accepts, with the strings `w` passing the test as prefixes, the witnesses of `W` after `u ++ w ++ r`. -/ -theorem acceptCount_trialVerifier (W : α × List Bool → Bool) (a : α) (u r seed : List Bool) +private theorem acceptCount_trialVerifier (W : α × List Bool → Bool) (a : α) (u r seed : List Bool) (M Z level : ℕ) : acceptCount (fun x => trialVerifier W a u r M level seed x.2) a (M + Z) = ∑ x : Fin M → Bool with hashesToZero level seed (List.ofFn x) = true, @@ -268,7 +269,7 @@ theorem acceptCount_trialVerifier (W : α × List Bool → Bool) (a : α) (u r s simp [acceptCount, htrial, hx] /-- All trials accept the product over the trials of one more than the count of one trial. -/ -theorem acceptCount_trialsVerifier (W : α × List Bool → Bool) (a : α) (u r : List Bool) +private theorem acceptCount_trialsVerifier (W : α × List Bool → Bool) (a : α) (u r : List Bool) (M Z T B : ℕ) (σ : Fin (T * B) → Bool) : acceptCount (fun x => trialsVerifier W a u r (List.ofFn σ) M Z T B x.2) a (T * (M + Z + 1)) = ∏ j : Fin T, (∑ x : Fin M → Bool with hashesToZero (j % (M + 3)) @@ -288,7 +289,7 @@ theorem acceptCount_trialsVerifier (W : α × List Bool → Bool) (a : α) (u r /-- The verifier of the existential quantifier on `u ++ (r ++ σ) ++ w` reads the prefix `u`, the inner random string `r` and the seeds `σ`, and runs `succTest` of all trials on `w`. -/ -theorem existsVerifier_append (ℓ m ρ ζ e : Polynomial ℕ) (W : α × List Bool → Bool) (a : α) +private theorem existsVerifier_append (ℓ m ρ ζ e : Polynomial ℕ) (W : α × List Bool → Bool) (a : α) (u r σ w : List Bool) (hu : u.length = ℓ.eval (enc a).length) (hr : r.length = ρ.eval (enc a).length) (hσ : σ.length = 4 * (e.eval (enc a).length + 1) * (m.eval (enc a).length + 3) * @@ -410,7 +411,7 @@ theorem exists_isRandomParityRep_alternation {V : α × List Bool → Bool} simp only [List.map_cons, alternation_true_cons, List.append_assoc] /-- Padding the witnesses of length `Z` to length `N ≥ Z` with `false`s keeps their number. -/ -theorem acceptCount_padWitness (W : α × List Bool → Bool) (a : α) (r : List Bool) {Z N : ℕ} +private theorem acceptCount_padWitness (W : α × List Bool → Bool) (a : α) (r : List Bool) {Z N : ℕ} (hZN : Z ≤ N) : acceptCount (fun x : (α × List Bool) × List Bool => W (x.1.1, x.1.2 ++ x.2.take Z) && !(x.2.drop Z).any fun b => b) (a, r) N = diff --git a/Complexity/Computability/Complexity/Classes/Toda/Isolation.lean b/Complexity/Computability/Complexity/Classes/Toda/Isolation.lean index 3e37bde39..4e5271013 100644 --- a/Complexity/Computability/Complexity/Classes/Toda/Isolation.lean +++ b/Complexity/Computability/Complexity/Classes/Toda/Isolation.lean @@ -96,7 +96,7 @@ theorem odd_one_add_prod_one_add {ι : Type*} [Fintype ι] (c : ι → ℕ) : /-- The functions `s : ι → X` whose values at the `t` distinct points `f i` lie in `F`: `F` is chosen at those points and anything elsewhere. -/ -theorem card_filter_forall_apply_mem {ι X : Type*} [Fintype ι] [DecidableEq ι] [Fintype X] +private theorem card_filter_forall_apply_mem {ι X : Type*} [Fintype ι] [DecidableEq ι] [Fintype X] [DecidableEq X] {t : ℕ} (f : Fin t → ι) (hf : Function.Injective f) (F : Finset X) : (univ.filter fun s : ι → X => ∀ i, s (f i) ∈ F).card = #F ^ t * Fintype.card X ^ (Fintype.card ι - t) := by @@ -147,7 +147,7 @@ theorem computableTidilyInPolyTime_hashesToZero {γ : Type} {input : γ ↪ List /-- The offsets of the Valiant–Vazirani equations are the row of `k` bits after the `k` rows of `M` coefficients. -/ -theorem listRow_eq_ofFn_offset (k M : ℕ) (seed : List Bool) : +private theorem listRow_eq_ofFn_offset (k M : ℕ) (seed : List Bool) : BitString.listRow k M seed = List.ofFn (ValiantVazirani.offset k M seed) := by rw [BitString.listRow, Nat.mul_comm M k] apply List.ext_getElem (by simp) @@ -242,14 +242,14 @@ theorem three_mul_two_pow_le_card_filter_card_eq_one {M B : ℕ} {S : Finset (Bi /-- `2 ^ (E + 1) * 13 ^ (4 (E + 1)) ≤ 16 ^ (4 (E + 1))`: `4 (E + 1)` rounds failing with probability at most `13 / 16` each all fail with probability at most `2 ^ (-(E + 1))`. -/ -theorem two_pow_mul_thirteen_pow_le (E : ℕ) : +private theorem two_pow_mul_thirteen_pow_le (E : ℕ) : 2 ^ (E + 1) * 13 ^ (4 * (E + 1)) ≤ 16 ^ (4 * (E + 1)) := by rw [pow_mul, pow_mul, ← mul_pow] exact Nat.pow_le_pow_left (by norm_num) _ /-- **The union bound for random strings**: if each `x` is bad for at most a `2 ^ (-e')` fraction of the random strings, some `x` of length `M` is bad for at most a `2 ^ (M - e')` fraction. -/ -theorem two_pow_mul_card_filter_exists_le {R M e' : ℕ} +private theorem two_pow_mul_card_filter_exists_le {R M e' : ℕ} {Bad : (Fin R → Bool) → (Fin M → Bool) → Prop} [∀ r x, Decidable (Bad r x)] (h : ∀ x, 2 ^ e' * (univ.filter fun r => Bad r x).card ≤ 2 ^ R) : diff --git a/Complexity/Computability/Complexity/Classes/ValiantVazirani.lean b/Complexity/Computability/Complexity/Classes/ValiantVazirani.lean index 117a47f1e..61fcff978 100644 --- a/Complexity/Computability/Complexity/Classes/ValiantVazirani.lean +++ b/Complexity/Computability/Complexity/Classes/ValiantVazirani.lean @@ -153,7 +153,7 @@ private theorem interpret_queryAnyStep (s : List (List Bool) × Bool) : /-- **Asking every word is strict oracle PPT**: each step copies one word onto the query buffer and reads one reply bit, and the list shrinks. -/ -theorem isOraclePPTOn_queryAny : +private theorem isOraclePPTOn_queryAny : IsOraclePPTOn (encList encBits) encBool (fun words => OracleComp.interpret ProbOracleComp.query (queryAny words)) := by simp only [queryAny, OracleComp.interpret_map, OracleComp.interpret_iterate] diff --git a/Complexity/Computability/Complexity/CookLevin/Correctness.lean b/Complexity/Computability/Complexity/CookLevin/Correctness.lean index 86cfa30ad..c3c99e48a 100644 --- a/Complexity/Computability/Complexity/CookLevin/Correctness.lean +++ b/Complexity/Computability/Complexity/CookLevin/Correctness.lean @@ -68,7 +68,7 @@ theorem eval_initClauses : /-- The input clauses at position `j`: the input head there reads the input symbol, a certificate bit included. -/ -theorem eval_inputClauses (t j : ℕ) : +private theorem eval_inputClauses (t j : ℕ) : (inputClauses (k := k) (State := State) u L t j).eval σ = true ↔ (σ (.holds t (.inPos j)) = true → σ (.holds t (.inRead (inputAt (u ++ certWord σ L) j))) = true) := by @@ -107,7 +107,7 @@ theorem eval_readClauses (t : ℕ) : fun ⟨h, h'⟩ => ⟨fun i z hz s ⟨hh, hc⟩ => h i z s hz hh hc, h'⟩⟩ /-- The accept clauses ask for a halted run with output `[true]`. -/ -theorem eval_acceptClauses : +private theorem eval_acceptClauses : (acceptClauses (k := k) (State := State) T).eval σ = true ↔ σ (.holds T (.state none)) = true ∧ σ (.holds T (.out (.one true))) = true := by simp [acceptClauses] @@ -117,7 +117,7 @@ section Soundness variable [Fintype State] /-- The situation clauses: a situation holds when its state and the symbols it reads do. -/ -theorem eval_sitClauses (t : ℕ) : +private theorem eval_sitClauses (t : ℕ) : (sitClauses (k := k) (State := State) t).eval σ = true ↔ ∀ y : Situation k State, σ (.holds t (.state (some y.1))) = true → σ (.holds t (.inRead y.2.1)) = true → (∀ i, σ (.holds t (.read i (y.2.2 i))) = true) → @@ -180,7 +180,7 @@ theorem eval_stepClauses (t : ℕ) : Clause.eval_impLits, List.forall_mem_map] /-- The one-hot clauses at time `t`. -/ -theorem eval_oneHotClauses (t : ℕ) : +private theorem eval_oneHotClauses (t : ℕ) : (oneHotClauses (k := k) (State := State) u L T t).eval σ = true ↔ ∀ g ∈ groups (u.length + L) T, (CNF.exactlyOne (g.map (.holds t))).eval σ = true := CNF.eval_flatMap_eq_true_iff .. @@ -213,7 +213,7 @@ theorem Agrees.of_oneHot {input : List Bool} {cfg : Cfg k Bool State input} {t : /-- One step of the induction: if `σ` describes `cfg` at time `t` and satisfies the clauses of time `t`, it describes the next configuration at time `t + 1`. -/ -theorem Agrees.step {cfg : Cfg k Bool State (u ++ certWord σ L)} {t : ℕ} +private theorem Agrees.step {cfg : Cfg k Bool State (u ++ certWord σ L)} {t : ℕ} (hA : Agrees σ (u.length + L) T t cfg) (hb : ∀ i, |cfg.workTapePos i| ≤ T) (hb' : ∀ i, |(tm.step cfg).workTapePos i| ≤ T) (hread : (readClauses u L T t).eval σ = true) (hsit : (sitClauses t).eval σ = true) @@ -267,7 +267,7 @@ noncomputable def runAssignment (tm : MultiTapeTM k Bool State) (u w : List Bool | .holds t φ => decide (φ.Holds (tm.runFrom (tm.initCfg (u ++ w)) t)) | .cert j => w.getD j false -theorem certWord_runAssignment {w : List Bool} (hw : w.length = L) : +private theorem certWord_runAssignment {w : List Bool} (hw : w.length = L) : certWord (runAssignment tm u w) L = w := by subst hw refine List.ext_getElem (by simp) fun j h₁ h₂ => ?_ diff --git a/Complexity/Computability/Complexity/CookLevin/Parsimonious.lean b/Complexity/Computability/Complexity/CookLevin/Parsimonious.lean index bf9d2b0e7..caed324bb 100644 --- a/Complexity/Computability/Complexity/CookLevin/Parsimonious.lean +++ b/Complexity/Computability/Complexity/CookLevin/Parsimonious.lean @@ -74,22 +74,22 @@ namespace Determined variable {n L T : ℕ} -theorem cert {j : ℕ} (hj : j < L) : Determined (State := State) (k := k) n L T (.cert j) := +private theorem cert {j : ℕ} (hj : j < L) : Determined (State := State) (k := k) n L T (.cert j) := Or.inl ⟨j, hj, rfl⟩ -theorem holds_basic {t : ℕ} (ht : t ≤ T) {φ : Feature k State} (hφ : φ ∈ basic n T) : +private theorem holds_basic {t : ℕ} (ht : t ≤ T) {φ : Feature k State} (hφ : φ ∈ basic n T) : Determined n L T (.holds t φ) := Or.inr (Or.inl ⟨t, ht, φ, hφ, rfl⟩) -theorem holds_read {t : ℕ} (ht : t < T) (i : Fin k) (s : Option Bool) : +private theorem holds_read {t : ℕ} (ht : t < T) (i : Fin k) (s : Option Bool) : Determined (State := State) n L T (.holds t (.read i s)) := Or.inr (Or.inr ⟨t, ht, Or.inl ⟨i, s, rfl⟩⟩) -theorem holds_inRead {t : ℕ} (ht : t < T) (s : Option Bool) : +private theorem holds_inRead {t : ℕ} (ht : t < T) (s : Option Bool) : Determined (State := State) (k := k) n L T (.holds t (.inRead s)) := Or.inr (Or.inr ⟨t, ht, Or.inr (Or.inl ⟨s, rfl⟩)⟩) -theorem holds_sit {t : ℕ} (ht : t < T) (y : Situation k State) : +private theorem holds_sit {t : ℕ} (ht : t < T) (y : Situation k State) : Determined n L T (.holds t (.sit y)) := Or.inr (Or.inr ⟨t, ht, Or.inr (Or.inr ⟨y, rfl⟩)⟩) @@ -241,7 +241,7 @@ theorem determined_of_mem_vars_tableau {v : Var k State} (hv : v ∈ (tableau tm · exact determined_of_mem_acceptClauses hc hl /-- When the tableau unrolls at least one step, it mentions every certificate bit. -/ -theorem cert_mem_vars_tableau (hT : 0 < T) {j : ℕ} (hj : j < L) : +private theorem cert_mem_vars_tableau (hT : 0 < T) {j : ℕ} (hj : j < L) : Var.cert j ∈ (tableau tm u L T).vars := by refine CNF.mem_vars.2 ⟨Clause.impLits [(.holds 0 (.inPos (u.length + 1 + j)), true), (.cert j, true)] (.holds 0 (.inRead (some true))), ?_, false, ?_⟩ @@ -313,7 +313,7 @@ theorem eq_runAssignment_of_eval_tableau (h : (tableau tm u L T).eval σ = true) /-- Two satisfying assignments with the same certificate agree on the variables of the tableau. -/ -theorem eq_of_eval_tableau_of_certWord_eq {τ : Var k State → Bool} +private theorem eq_of_eval_tableau_of_certWord_eq {τ : Var k State → Bool} (hσ : (tableau tm u L T).eval σ = true) (hτ : (tableau tm u L T).eval τ = true) (hc : certWord σ L = certWord τ L) {v : Var k State} (hv : v ∈ (tableau tm u L T).vars) : σ v = τ v := by @@ -321,7 +321,7 @@ theorem eq_of_eval_tableau_of_certWord_eq {τ : Var k State → Bool} rw [eq_runAssignment_of_eval_tableau hσ hd, eq_runAssignment_of_eval_tableau hτ hd, hc] /-- A tableau unrolled for no step is unsatisfiable: the initial configuration is running. -/ -theorem eval_tableau_zero : (tableau tm u L 0).eval σ = false := by +private theorem eval_tableau_zero : (tableau tm u L 0).eval σ = false := by by_contra h have hz := (exists_eval_tableau_iff (tm := tm) (u := u) (T := 0) (z := certWord σ L)).1 ⟨σ, by rw [length_certWord], by rw [length_certWord]; simpa using h⟩ diff --git a/Complexity/Computability/Complexity/Fagin/Converse.lean b/Complexity/Computability/Complexity/Fagin/Converse.lean index fc85926b4..86184508f 100644 --- a/Complexity/Computability/Complexity/Fagin/Converse.lean +++ b/Complexity/Computability/Complexity/Fagin/Converse.lean @@ -98,15 +98,15 @@ arities of `v`. -/ def maxArity : ℕ := Finset.univ.sup v.arity + 1 -theorem one_le_maxArity : 1 ≤ v.maxArity := +private theorem one_le_maxArity : 1 ≤ v.maxArity := Nat.le_add_left 1 _ -theorem arity_le_maxArity (i : Fin v.count) : v.arity i ≤ v.maxArity := +private theorem arity_le_maxArity (i : Fin v.count) : v.arity i ≤ v.maxArity := (Finset.le_sup (Finset.mem_univ i)).trans (Nat.le_add_right _ 1) /-- For a well-formed input `a` with `1 ≤ a.1`, the `m`-th prefix of `encStructure a` has length at most `(m + 1) * (2 * a.1 ^ v.maxArity + 1)`. -/ -theorem length_encStructurePrefix_le_pow {a : EncodedStructure} (ha : v.WellFormed a) +private theorem length_encStructurePrefix_le_pow {a : EncodedStructure} (ha : v.WellFormed a) (ha1 : 1 ≤ a.1) (m : ℕ) (hm : m ≤ v.count) : (v.encStructurePrefix a m).length ≤ (m + 1) * (2 * a.1 ^ v.maxArity + 1) := by induction m with diff --git a/Complexity/Computability/Complexity/Fagin/Layout.lean b/Complexity/Computability/Complexity/Fagin/Layout.lean index 83b837a3a..4360a57f0 100644 --- a/Complexity/Computability/Complexity/Fagin/Layout.lean +++ b/Complexity/Computability/Complexity/Fagin/Layout.lean @@ -346,7 +346,7 @@ theorem length_encStructurePrefix {a : EncodedStructure} {m : ℕ} (hm : m ≤ a rw [encStructurePrefix, htake, List.length_append, length_frame, length_flatMap_frame, tableStart, encUnary_apply, List.length_replicate] -theorem length_encStructurePrefix_le (a : EncodedStructure) {m : ℕ} (hm : m ≤ v.count) : +private theorem length_encStructurePrefix_le (a : EncodedStructure) {m : ℕ} (hm : m ≤ v.count) : (v.encStructurePrefix a m).length ≤ (v.encStructurePrefix a v.count).length := by simp only [encStructurePrefix, List.length_append] exact Nat.add_le_add_left (((List.take_sublist_take_left hm).flatMap frame).length_le) _ diff --git a/Complexity/Computability/Complexity/Fagin/Ordered.lean b/Complexity/Computability/Complexity/Fagin/Ordered.lean index 26cf2d26e..79ce4f7c6 100644 --- a/Complexity/Computability/Complexity/Fagin/Ordered.lean +++ b/Complexity/Computability/Complexity/Fagin/Ordered.lean @@ -61,7 +61,7 @@ theorem Definable.esoDefinable {L : Language.{u, v}} {K : Query L} (hK : Definab /-- The existing fixed-sentence encoding is exactly the new arbitrary-query encoding applied to the class defined by that sentence. Its size and shape rejection behavior is unchanged. -/ -theorem encodedLanguage_sentence {L : Language} [L.IsRelational] (v : Vocabulary L) +private theorem encodedLanguage_sentence {L : Language} [L.IsRelational] (v : Vocabulary L) (φ : (language L).Sentence) : Query.encodedLanguage {M : Ordered.Structure L | φ.Realize M} v = queryLanguage v φ := rfl @@ -76,7 +76,7 @@ theorem Definable.encodedLanguage_mem_NP {L : Language} [L.IsRelational] (v : Vo /-- The one-dimensional interpretation retaining the input relations and reading strict order from canonical non-strict order. -/ -def strictOrderInterpretation (L : Language.{u, v}) : +private def strictOrderInterpretation (L : Language.{u, v}) : FO.Interpretation (language L) (L.sum ESO.orderLanguage) Unit where domain := ⊤ rel := fun {n} r => match r with @@ -88,7 +88,7 @@ def strictOrderInterpretation (L : Language.{u, v}) : fun i => .var (if i = 0 then 1 else 0, ())) /-- The canonical strict-order structure interpreted above is the original ordered universe. -/ -def strictOrderEquiv {L : Language.{u, v}} [L.IsRelational] (M : Ordered.Structure L) : +private def strictOrderEquiv {L : Language.{u, v}} [L.IsRelational] (M : Ordered.Structure L) : letI := ESO.varLanguage.structure (arity := fun _ : Unit => 2) (ESO.orderRelOfEquiv (Equiv.refl M)); (strictOrderInterpretation L).Model M ≃[L.sum ESO.orderLanguage] M := by @@ -112,7 +112,7 @@ def strictOrderEquiv {L : Language.{u, v}} [L.IsRelational] (M : Ordered.Structu /-- Pulling a strict-order ESO sentence into the public ordered language preserves its truth on the fixed canonical order. -/ -theorem realize_onESOSentence_strictOrder {L : Language.{u, v}} [L.IsRelational] +private theorem realize_onESOSentence_strictOrder {L : Language.{u, v}} [L.IsRelational] (M : Ordered.Structure L) (Φ : ESO.Sentence (L.sum ESO.orderLanguage)) : ((strictOrderInterpretation L).onESOSentence Φ).Realize M ↔ letI := ESO.varLanguage.structure (arity := fun _ : Unit => 2) diff --git a/Complexity/Computability/Complexity/Fagin/Small.lean b/Complexity/Computability/Complexity/Fagin/Small.lean index 2eeb62a1a..6970bef94 100644 --- a/Complexity/Computability/Complexity/Fagin/Small.lean +++ b/Complexity/Computability/Complexity/Fagin/Small.lean @@ -95,7 +95,7 @@ def encodeOfOne (s : Fin v.count → Bool) : EncodedStructure := (1, List.ofFn fun i : Fin v.count => [s i]) open scoped Classical in -theorem relTable_eq_of_equiv_fin_zero {N : Type} [L.Structure N] (e : N ≃ Fin 0) +private theorem relTable_eq_of_equiv_fin_zero {N : Type} [L.Structure N] (e : N ≃ Fin 0) (r : Σ n, L.Relations n) : Vocabulary.relTable N e r = if r.1 = 0 then [decide (N ⊨ nullaryRelSentence r)] else [] := by @@ -110,13 +110,13 @@ theorem relTable_eq_of_equiv_fin_zero {N : Type} [L.Structure N] (e : N ≃ Fin · simp [Vocabulary.relTable] open scoped Classical in -theorem encode_eq_encodeOfZero {N : Type} [L.Structure N] (e : N ≃ Fin 0) : +private theorem encode_eq_encodeOfZero {N : Type} [L.Structure N] (e : N ≃ Fin 0) : v.encode N e = v.encodeOfZero (fun i => decide (N ⊨ v.nullarySymbolSentence i)) := by refine Prod.ext rfl (congrArg List.ofFn (funext fun i => ?_)) exact relTable_eq_of_equiv_fin_zero e (v.symbol i) open scoped Classical in -theorem relTable_eq_of_equiv_fin_one {N : Type} [L.Structure N] (e : N ≃ Fin 1) +private theorem relTable_eq_of_equiv_fin_one {N : Type} [L.Structure N] (e : N ≃ Fin 1) (r : Σ n, L.Relations n) : Vocabulary.relTable N e r = [decide (N ⊨ constTupleRelSentence r)] := by refine List.ext_getElem (by simp [Vocabulary.relTable]) fun j hj₁ hj₂ => ?_ @@ -140,7 +140,7 @@ theorem relTable_eq_of_equiv_fin_one {N : Type} [L.Structure N] (e : N ≃ Fin 1 exact h (e.symm 0) open scoped Classical in -theorem encode_eq_encodeOfOne {N : Type} [L.Structure N] (e : N ≃ Fin 1) : +private theorem encode_eq_encodeOfOne {N : Type} [L.Structure N] (e : N ≃ Fin 1) : v.encode N e = v.encodeOfOne (fun i => decide (N ⊨ v.constTupleSentence i)) := by refine Prod.ext rfl (congrArg List.ofFn (funext fun i => ?_)) exact relTable_eq_of_equiv_fin_one e (v.symbol i) @@ -154,7 +154,8 @@ variable [L.IsRelational] (v : Vocabulary L) include v in /-- For any isomorphism-closed class `K` over a finite relational vocabulary, the restriction of `K` to empty structures (`Nat.card M = 0`) is first-order definable. -/ -theorem Definable.inter_card_eq_zero {K : Set (Bundled.{0} L.Structure)} (hK : IsoClosed K) : +private theorem Definable.inter_card_eq_zero {K : Set (Bundled.{0} L.Structure)} + (hK : IsoClosed K) : Definable {M : Bundled.{0} L.Structure | M ∈ K ∧ Nat.card M = 0} := by refine ⟨cardEqSentence L 0 ⊓ truthTableSentence v.nullarySymbolSentence (fun s => v.decoded (v.encodeOfZero s) ∈ K), fun M _ => ?_⟩ @@ -176,7 +177,7 @@ theorem Definable.inter_card_eq_zero {K : Set (Bundled.{0} L.Structure)} (hK : I include v in /-- For any isomorphism-closed class `K` over a finite relational vocabulary, the restriction of `K` to singleton structures (`Nat.card M = 1`) is first-order definable. -/ -theorem Definable.inter_card_eq_one {K : Set (Bundled.{0} L.Structure)} (hK : IsoClosed K) : +private theorem Definable.inter_card_eq_one {K : Set (Bundled.{0} L.Structure)} (hK : IsoClosed K) : Definable {M : Bundled.{0} L.Structure | M ∈ K ∧ Nat.card M = 1} := by refine ⟨cardEqSentence L 1 ⊓ truthTableSentence v.constTupleSentence (fun s => v.decoded (v.encodeOfOne s) ∈ K), fun M _ => ?_⟩ diff --git a/Complexity/Computability/Complexity/Fagin/Tableau/Semantics.lean b/Complexity/Computability/Complexity/Fagin/Tableau/Semantics.lean index 6ac1dd9b8..6218326b2 100644 --- a/Complexity/Computability/Complexity/Fagin/Tableau/Semantics.lean +++ b/Complexity/Computability/Complexity/Fagin/Tableau/Semantics.lean @@ -214,7 +214,8 @@ structure TableauRels.AgreesAt (r : TableauRels L' m State) include hlt in /-- Semantic characterization of `inReadFormula` under `AgreesAt`. -/ -theorem realize_inReadFormula {u w : List Bool} {cfg : Cfg m Bool State (u ++ w)} {t : Fin B} +private theorem realize_inReadFormula {u w : List Bool} {cfg : Cfg m Bool State (u ++ w)} + {t : Fin B} (heB : u.length + w.length + 1 < B) (huLen : ∀ z : Fin B, RelMap r.uLen ![z] ↔ (z : ℕ) = u.length) (huBit : ∀ p : Fin B, (p : ℕ) < u.length → (RelMap r.uBit ![p] ↔ u[(p : ℕ)]? = some true)) @@ -235,7 +236,7 @@ theorem realize_inReadFormula {u w : List Bool} {cfg : Cfg m Bool State (u ++ w) exact ⟨![(⟨cfg.inputPos.val, by omega⟩ : Fin B)], rfl, hs⟩ /-- Semantic characterization of `readFormula` under `AgreesAt`. -/ -theorem realize_readFormula {input : List Bool} {cfg : Cfg m Bool State input} {t : Fin B} +private theorem realize_readFormula {input : List Bool} {cfg : Cfg m Bool State input} {t : Fin B} (hb : ∀ i : Fin m, |cfg.workTapePos i| < B) (hA : r.AgreesAt cfg t) (i : Fin m) (s : Option Bool) {V : Type*} (vT : V) (env : V → Fin B) (ht : env vT = t) : (readFormula r i s vT).Realize env ↔ (Feature.read i s).Holds cfg := by @@ -276,7 +277,8 @@ theorem realize_sitFormula {u w : List Bool} {cfg : Cfg m Bool State (u ++ w)} { include hlt in /-- Semantic characterization of `inPosPrevFormula` under `AgreesAt`. -/ -theorem realize_inPosPrevFormula {u w : List Bool} {cfg : Cfg m Bool State (u ++ w)} {t : Fin B} +private theorem realize_inPosPrevFormula {u w : List Bool} {cfg : Cfg m Bool State (u ++ w)} + {t : Fin B} (heB : u.length + w.length + 1 < B) (hend : ∀ z : Fin B, RelMap r.endPos ![z] ↔ (z : ℕ) = u.length + w.length) (hA : r.AgreesAt cfg t) @@ -326,7 +328,7 @@ theorem realize_inPosPrevFormula {u w : List Bool} {cfg : Cfg m Bool State (u ++ include hlt in /-- Semantic characterization of `headPrevFormula`. -/ -theorem realize_headPrevFormula {headSame headOpp : L'.Relations 2} {t : Fin B} +private theorem realize_headPrevFormula {headSame headOpp : L'.Relations 2} {t : Fin B} {pos : ℤ} (hb : |pos| + 1 < B) {sign : ℤ} (hsign : sign = 1 ∨ sign = -1) (hSame : ∀ a : Fin B, RelMap headSame ![t, a] ↔ pos = sign * (a : ℤ)) (hOpp : ∀ a : Fin B, RelMap headOpp ![t, a] ↔ pos = -sign * (a : ℤ)) diff --git a/Complexity/Computability/Complexity/Fagin/Verifier.lean b/Complexity/Computability/Complexity/Fagin/Verifier.lean index 86c58335d..31e59c4ca 100644 --- a/Complexity/Computability/Complexity/Fagin/Verifier.lean +++ b/Complexity/Computability/Complexity/Fagin/Verifier.lean @@ -91,7 +91,7 @@ structure Layout where arity_le : ∀ i, Φ.arity i ≤ degree /-- Every sentence has a layout, numbering its finitely many relation variables. -/ -noncomputable def Layout.ofFinite : Layout Φ where +private noncomputable def Layout.ofFinite : Layout Φ where blocks := Nat.card Φ.Var block := (Finite.equivFin Φ.Var).toEmbedding degree := ⨆ i, Φ.arity i @@ -116,7 +116,7 @@ for an input of encoded length `N`. -/ def position (N : ℕ) (i : Φ.Var) (idx : ℕ) : ℕ := ℓ.block i * N ^ ℓ.degree + idx -theorem position_lt (N : ℕ) (i : Φ.Var) {idx : ℕ} (h : idx < N ^ ℓ.degree) : +private theorem position_lt (N : ℕ) (i : Φ.Var) {idx : ℕ} (h : idx < N ^ ℓ.degree) : ℓ.position N i idx < ℓ.blocks * N ^ ℓ.degree := by unfold position calc ℓ.block i * N ^ ℓ.degree + idx < (ℓ.block i + 1) * N ^ ℓ.degree := by @@ -140,7 +140,7 @@ theorem position_injective (N : ℕ) {i j : Φ.Var} {idx idx' : ℕ} (h : idx < /-- The number of tuples of the arity of a relation variable is at most the block size, for inputs of cardinality at most `N`. -/ -theorem pow_arity_le {n N : ℕ} (hn : n ≤ N) (hN : 0 < N) (i : Φ.Var) : +private theorem pow_arity_le {n N : ℕ} (hn : n ≤ N) (hN : 0 < N) (i : Φ.Var) : n ^ Φ.arity i ≤ N ^ ℓ.degree := (Nat.pow_le_pow_left hn _).trans (Nat.pow_le_pow_right hN (ℓ.arity_le i)) @@ -152,17 +152,18 @@ def certRel (n N : ℕ) (w : List Bool) (i : Φ.Var) : Set (Fin (Φ.arity i) → open scoped Classical in /-- The certificate encoding relations `R` on `Fin n`, for inputs of encoded length `N`: the bit at the position of a tuple is its membership in the relation, and the other bits are clear. -/ -noncomputable def certificate (n N : ℕ) (R : ∀ i, Set (Fin (Φ.arity i) → Fin n)) : List Bool := +private noncomputable def certificate (n N : ℕ) (R : ∀ i, Set (Fin (Φ.arity i) → Fin n)) + : List Bool := (List.range (ℓ.blocks * N ^ ℓ.degree)).map fun pos => decide (∃ (i : Φ.Var) (x : Fin (Φ.arity i) → Fin n), pos = ℓ.position N i (tupleIndex x) ∧ x ∈ R i) -theorem length_certificate (n N : ℕ) (R : ∀ i, Set (Fin (Φ.arity i) → Fin n)) : +private theorem length_certificate (n N : ℕ) (R : ∀ i, Set (Fin (Φ.arity i) → Fin n)) : (ℓ.certificate n N R).length = ℓ.blocks * N ^ ℓ.degree := by simp [certificate] /-- Reading the certificate of `R` gives back `R`, when every tuple has a bit. -/ -theorem certRel_certificate {n N : ℕ} (hn : n ≤ N) (hN : 0 < N) +private theorem certRel_certificate {n N : ℕ} (hn : n ≤ N) (hN : 0 < N) (R : ∀ i, Set (Fin (Φ.arity i) → Fin n)) : ℓ.certRel n N (ℓ.certificate n N R) = R := by funext i ext x @@ -235,7 +236,7 @@ section Correctness variable {v} {a : EncodedStructure} {N : ℕ} {w : List Bool} -theorem termValue_ofFn {k : ℕ} (xs : Fin k → Fin a.1) +private theorem termValue_ofFn {k : ℕ} (xs : Fin k → Fin a.1) (t : (L.sum (varLanguage Φ.arity)).Term (Empty ⊕ Fin k)) : termValue (Φ := Φ) (List.ofFn fun j => (xs j : ℕ)) t = Fin.val (Sum.elim (default : Empty → Fin a.1) xs (FO.termVar t)) := by @@ -244,7 +245,7 @@ theorem termValue_ofFn {k : ℕ} (xs : Fin k → Fin a.1) · exact e.elim · simp [varPos] -theorem termsIndex_ofFn {k : ℕ} (xs : Fin k → Fin a.1) : +private theorem termsIndex_ofFn {k : ℕ} (xs : Fin k → Fin a.1) : ∀ {l : ℕ} (ts : Fin l → (L.sum (varLanguage Φ.arity)).Term (Empty ⊕ Fin k)), termsIndex (Φ := Φ) a.1 (List.ofFn fun j => (xs j : ℕ)) ts = tupleIndex fun j => Sum.elim (default : Empty → Fin a.1) xs (FO.termVar (ts j)) @@ -265,7 +266,7 @@ theorem relBit_eq_true_iff {l : ℕ} (R : (L.sum (varLanguage Φ.arity)).Relatio · change _ ↔ y ∘ Fin.cast r.2 ∈ ℓ.certRel a.1 N w r.1 simp only [certRel, Set.mem_ofPred_eq, relBit, tupleIndex_comp_cast] -theorem ofFn_val_snoc {k : ℕ} (xs : Fin k → Fin a.1) (x : Fin a.1) : +private theorem ofFn_val_snoc {k : ℕ} (xs : Fin k → Fin a.1) (x : Fin a.1) : (List.ofFn fun j => ((Fin.snoc xs x : Fin (k + 1) → Fin a.1) j : ℕ)) = (List.ofFn fun j => (xs j : ℕ)) ++ [(x : ℕ)] := by rw [List.ofFn_succ', List.concat_eq_append] @@ -377,7 +378,7 @@ theorem _root_.Cslib.Logic.Vocabulary.computableTidilyInPolyTime_table (r : Σ n (const (encMid := encUnary) (v.index r))) /-- The cardinality of the input, in unary. -/ -theorem computableTidilyInPolyTime_card {a : γ → EncodedStructure} +private theorem computableTidilyInPolyTime_card {a : γ → EncodedStructure} (ha : ComputableTidilyInPolyTime a encIn encStructure) : ComputableTidilyInPolyTime (fun x => (a x).1) encIn encUnary := (fst encUnary (encList encBits)).comp ha diff --git a/Complexity/Computability/Complexity/FineGrained/Assignment.lean b/Complexity/Computability/Complexity/FineGrained/Assignment.lean index 20e8dcf7e..38720354f 100644 --- a/Complexity/Computability/Complexity/FineGrained/Assignment.lean +++ b/Complexity/Computability/Complexity/FineGrained/Assignment.lean @@ -91,7 +91,7 @@ open Cslib.Logic.PL Turing.MultiTapeTM namespace ThreeSAT -theorem mem_vars_of_mem_distinctVars {φ : CNF ℕ} {v : ℕ} (hv : v ∈ distinctVars φ) : +private theorem mem_vars_of_mem_distinctVars {φ : CNF ℕ} {v : ℕ} (hv : v ∈ distinctVars φ) : v ∈ φ.vars := by simp only [distinctVars, List.mem_map, List.mem_filter, Prod.exists, exists_and_right, exists_eq_right] at hv diff --git a/Complexity/Computability/Complexity/FineGrained/BruteForce.lean b/Complexity/Computability/Complexity/FineGrained/BruteForce.lean index eab32fdc1..4fdfab4ad 100644 --- a/Complexity/Computability/Complexity/FineGrained/BruteForce.lean +++ b/Complexity/Computability/Complexity/FineGrained/BruteForce.lean @@ -84,7 +84,7 @@ assignment to try, and whether a satisfying assignment was found. -/ abbrev State : Type := (CNF ℕ × List ℕ) × (ℕ × Bool) /-- States encoded as framed tuples. -/ -abbrev encState : State ↪ List Bool := +private abbrev encState : State ↪ List Bool := encPair (encPair encCNF (encList encNat)) (encPair encNat encBool) /-- Try the next numbered assignment. -/ @@ -98,7 +98,7 @@ def init (φ : CNF ℕ) : State := ((φ, ThreeSAT.distinctVars φ), (0, false)) variables of the formula. -/ def search (φ : CNF ℕ) : Bool := (step^[2 ^ (ThreeSAT.distinctVars φ).length] (init φ)).2.2 -theorem iterate_step_init (φ : CNF ℕ) (k : ℕ) : +private theorem iterate_step_init (φ : CNF ℕ) (k : ℕ) : step^[k] (init φ) = ((φ, ThreeSAT.distinctVars φ), (k, (List.range k).any fun i => φ.eval (bitsAssignment (ThreeSAT.distinctVars φ) i))) := by induction k with @@ -117,7 +117,8 @@ theorem search_eq_true_iff (φ : CNF ℕ) : search φ = true ↔ φ ∈ SAT := b open ComputableTidilyInPolyTime in /-- A step of exhaustive search is polynomial-time. -/ -theorem computableTidilyInPolyTime_step : ComputableTidilyInPolyTime step encState encState := by +private theorem computableTidilyInPolyTime_step + : ComputableTidilyInPolyTime step encState encState := by have h : ComputableTidilyInPolyTime (fun s : State => s.1.1.eval (bitsAssignment s.1.2 s.2.1)) encState encBool := computableTidilyInPolyTime_eval_bitsAssignment.comp @@ -128,13 +129,14 @@ theorem computableTidilyInPolyTime_step : ComputableTidilyInPolyTime step encSta open ComputableTidilyInPolyTime in /-- The initial state is computed in polynomial time. -/ -theorem computableTidilyInPolyTime_init : ComputableTidilyInPolyTime init encCNF encState := by +private theorem computableTidilyInPolyTime_init + : ComputableTidilyInPolyTime init encCNF encState := by unfold init fun_prop open ComputableTidilyInPolyTime in /-- The number `2 ^ n` of rounds is computed in binary in polynomial time. -/ -theorem computableTidilyInPolyTime_count : +private theorem computableTidilyInPolyTime_count : ComputableTidilyInPolyTime (fun φ => 2 ^ (ThreeSAT.distinctVars φ).length) encCNF encNat := by fun_prop diff --git a/Complexity/Computability/Complexity/FineGrained/Sparsification.lean b/Complexity/Computability/Complexity/FineGrained/Sparsification.lean index 083763bee..7e88f141d 100644 --- a/Complexity/Computability/Complexity/FineGrained/Sparsification.lean +++ b/Complexity/Computability/Complexity/FineGrained/Sparsification.lean @@ -84,7 +84,7 @@ open ClauseSet.Sparsification (threshold base one_le_threshold BranchingRule) abbrev State : Type := List (CNF ℕ) × Bool /-- States encoded as framed tuples. -/ -abbrev encState : State ↪ List Bool := encPair (encList encCNF) encBool +private abbrev encState : State ↪ List Bool := encPair (encList encCNF) encBool /-- One step of the depth-first search of the sparsification tree, for width `K` and the thresholds `threshold K α`: a sparse formula on top of the stack is popped and the decider `g` is @@ -113,11 +113,12 @@ def search (K α k M : ℕ) (g : CNF ℕ → Bool) (φ : CNF ℕ) : Bool := variable {K α : ℕ} (hK : 1 ≤ K) (hα : 1 ≤ α) /-- The list-level branching rule for width `K` and the thresholds `threshold K α`. -/ -abbrev rule : BranchingRule (threshold K α) ℕ {ψ : CNF ℕ // Normalized K ψ} := +private abbrev rule : BranchingRule (threshold K α) ℕ {ψ : CNF ℕ // Normalized K ψ} := CNF.Sparsification.rule (one_le_threshold hK hα) K include hK hα in -theorem step_map (g : CNF ℕ → Bool) (stk : List {ψ : CNF ℕ // Normalized K ψ}) (acc : Bool) : +private theorem step_map (g : CNF ℕ → Bool) (stk : List {ψ : CNF ℕ // Normalized K ψ}) + (acc : Bool) : step K α g (stk.map Subtype.val, acc) = Prod.map (List.map Subtype.val) id ((rule hK hα).searchStep (g ∘ Subtype.val) (stk, acc)) := by @@ -133,7 +134,8 @@ theorem step_map (g : CNF ℕ → Bool) (stk : List {ψ : CNF ℕ // Normalized simp [step, BranchingRule.searchStep, hs, hs', rule, CNF.Sparsification.rule] include hK hα in -theorem iterate_step_map (g : CNF ℕ → Bool) (n : ℕ) (stk : List {ψ : CNF ℕ // Normalized K ψ}) +private theorem iterate_step_map (g : CNF ℕ → Bool) (n : ℕ) + (stk : List {ψ : CNF ℕ // Normalized K ψ}) (acc : Bool) : (step K α g)^[n] (stk.map Subtype.val, acc) = Prod.map (List.map Subtype.val) id @@ -145,15 +147,15 @@ theorem iterate_step_map (g : CNF ℕ → Bool) (n : ℕ) (stk : List {ψ : CNF obtain ⟨stk', acc'⟩ := (rule hK hα).searchStep (g ∘ Subtype.val) (stk, acc) exact ih stk' acc' -theorem step_nil (g : CNF ℕ → Bool) (acc : Bool) : step K α g ([], acc) = ([], acc) := rfl +private theorem step_nil (g : CNF ℕ → Bool) (acc : Bool) : step K α g ([], acc) = ([], acc) := rfl -theorem iterate_step_nil (g : CNF ℕ → Bool) (n : ℕ) (acc : Bool) : +private theorem iterate_step_nil (g : CNF ℕ → Bool) (n : ℕ) (acc : Bool) : (step K α g)^[n] ([], acc) = ([], acc) := Function.iterate_fixed (step_nil g acc) n /-! ### The root -/ -theorem normalized_root {k : ℕ} (hkK : k ≤ K) (φ : CNF ℕ) : Normalized K (root k φ) := by +private theorem normalized_root {k : ℕ} (hkK : k ≤ K) (φ : CNF ℕ) : Normalized K (root k φ) := by unfold root split_ifs with h · simp only [List.all_eq_true, decide_eq_true_eq] at h @@ -161,7 +163,7 @@ theorem normalized_root {k : ℕ} (hkK : k ≤ K) (φ : CNF ℕ) : Normalized K · exact ⟨by simp, by simp, by simp, by simp [CNF.toClauseSet, ClauseSet.Sparsification.Reduced]⟩ /-- Every clause of the root has the literals of a clause of the formula. -/ -theorem exists_of_mem_root {k : ℕ} {φ : CNF ℕ} {C : Clause ℕ} (hC : C ∈ root k φ) : +private theorem exists_of_mem_root {k : ℕ} {φ : CNF ℕ} {C : Clause ℕ} (hC : C ∈ root k φ) : ∃ D ∈ φ, C.toFinset = D.toFinset := by unfold root at hC split_ifs at hC @@ -171,7 +173,7 @@ theorem exists_of_mem_root {k : ℕ} {φ : CNF ℕ} {C : Clause ℕ} (hC : C ∈ exact ⟨D, hD, toFinset_dedup D⟩ · simp at hC -theorem length_root_le (k : ℕ) (φ : CNF ℕ) : (root k φ).length ≤ φ.length := by +private theorem length_root_le (k : ℕ) (φ : CNF ℕ) : (root k φ).length ≤ φ.length := by unfold root split_ifs · exact ((reduce_sublist _).trans (dedupClauses_sublist _)).length_le.trans @@ -179,10 +181,10 @@ theorem length_root_le (k : ℕ) (φ : CNF ℕ) : (root k φ).length ≤ φ.leng · exact Nat.zero_le _ /-- The root as a state of the list-level rule. -/ -def rootState {k : ℕ} (hkK : k ≤ K) (φ : CNF ℕ) : {ψ : CNF ℕ // Normalized K ψ} := +private def rootState {k : ℕ} (hkK : k ≤ K) (φ : CNF ℕ) : {ψ : CNF ℕ // Normalized K ψ} := ⟨root k φ, normalized_root hkK φ⟩ -theorem mem_vars_of_mem_root {k : ℕ} {φ : CNF ℕ} : +private theorem mem_vars_of_mem_root {k : ℕ} {φ : CNF ℕ} : ∀ C ∈ (root k φ).toClauseSet, ∀ l ∈ C, l.1 ∈ φ.vars.toFinset := by intro C hC l hl obtain ⟨C', hC', rfl⟩ := mem_toClauseSet.mp hC @@ -201,7 +203,7 @@ variable {k : ℕ} (hkK : k ≤ K) {φ : CNF ℕ} {w : List Bool} include hK hα hkK /-- Every clause of a state of the tree has its literals in a clause of the formula. -/ -theorem exists_of_mem_walk (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) {C : Clause ℕ} +private theorem exists_of_mem_walk (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) {C : Clause ℕ} (hC : C ∈ ((rule hK hα).walk (rootState hkK φ) w).1) : ∃ D ∈ φ, C.toFinset ⊆ D.toFinset := by obtain ⟨D', hD', hCD'⟩ := BranchingRule.IsNodeWord.refines_walk (one_le_threshold hK hα) hw @@ -211,7 +213,7 @@ theorem exists_of_mem_walk (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) exact ⟨D, hD, hDeq ▸ hCD'⟩ /-- The states of the tree have at most `m + n K X ^ (2 K)` clauses. -/ -theorem length_walk_le (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) : +private theorem length_walk_le (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) : ((rule hK hα).walk (rootState hkK φ) w).1.length ≤ φ.length + φ.numVars * (K * base K α ^ (2 * K)) := by have h : (((rule hK hα).walk (rootState hkK φ) w).1.toClauseSet).card ≤ @@ -225,7 +227,7 @@ theorem length_walk_le (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) : /-- **The leaves are small.** The sparse states of the tree have at most `c n + 1` clauses, for `c = occBound K α`. -/ -theorem length_walk_le_of_isSparse (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) +private theorem length_walk_le_of_isSparse (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) (hs : isSparse (threshold K α) K ((rule hK hα).walk (rootState hkK φ) w).1 = true) : ((rule hK hα).walk (rootState hkK φ) w).1.length ≤ occBound K α * φ.numVars + 1 := by set ψ := (rule hK hα).walk (rootState hkK φ) w @@ -239,7 +241,7 @@ theorem length_walk_le_of_isSparse (hw : (rule hK hα).IsNodeWord (rootState hkK exact List.mem_toFinset.mpr (List.mem_map.mpr ⟨l, List.mem_flatten.mpr ⟨D, hD, hl'⟩, rfl⟩) /-- The states of the tree from a formula of width `k` have width `k`. -/ -theorem length_le_of_mem_walk (hφ : ∀ c ∈ φ, c.length ≤ k) +private theorem length_le_of_mem_walk (hφ : ∀ c ∈ φ, c.length ≤ k) (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) {C : Clause ℕ} (hC : C ∈ ((rule hK hα).walk (rootState hkK φ) w).1) : C.length ≤ k := by obtain ⟨D, hD, hCD⟩ := exists_of_mem_walk hK hα hkK hw hC @@ -260,7 +262,7 @@ open Classical in /-- **The run of the search.** After the rounds, the stack is empty and the accumulator records whether the decider accepts a leaf of the tree. Meanwhile the stack holds at most `n K X ^ (2 K) + 1` states of the tree. -/ -theorem iterate_step {k M : ℕ} (hkK : k ≤ K) (hM : LeafBound K α M) (g : CNF ℕ → Bool) +private theorem iterate_step {k M : ℕ} (hkK : k ≤ K) (hM : LeafBound K α M) (g : CNF ℕ → Bool) (φ : CNF ℕ) : (step K α g)^[rounds M φ] ([root k φ], false) = ([], decide (∃ w, (rule hK hα).IsLeafWord (rootState hkK φ) w ∧ @@ -340,7 +342,7 @@ section PolyTime open ComputableTidilyInPolyTime -theorem computableTidilyInPolyTime_isSparse_head (K α : ℕ) : +private theorem computableTidilyInPolyTime_isSparse_head (K α : ℕ) : ComputableTidilyInPolyTime (fun s : State => isSparse (threshold K α) K (s.1.headD [])) encState encBool := by have h := computableTidilyInPolyTime_isSparse encNat @@ -350,7 +352,7 @@ theorem computableTidilyInPolyTime_isSparse_head (K α : ℕ) : fun_prop exact h.comp hH -theorem computableTidilyInPolyTime_inner (K α : ℕ) : +private theorem computableTidilyInPolyTime_inner (K α : ℕ) : ComputableTidilyInPolyTime (fun s : State => (next (threshold K α) K (s.1.headD []) false :: next (threshold K α) K (s.1.headD []) true :: s.1.tail, s.2)) encState encState := by have h := computableTidilyInPolyTime_next encNat @@ -358,14 +360,14 @@ theorem computableTidilyInPolyTime_inner (K α : ℕ) : unfold encState encCNF fun_prop -theorem computableTidilyInPolyTime_root (k : ℕ) : +private theorem computableTidilyInPolyTime_root (k : ℕ) : ComputableTidilyInPolyTime (fun φ : CNF ℕ => (([root k φ], false) : State)) encCNF encState := by have h := computableTidilyInPolyTime_normalize encNat unfold root encState encCNF fun_prop -theorem computableTidilyInPolyTime_rounds (M : ℕ) : +private theorem computableTidilyInPolyTime_rounds (M : ℕ) : ComputableTidilyInPolyTime (rounds M) encCNF encNat := by have h := unary_div_const M unfold rounds @@ -373,7 +375,7 @@ theorem computableTidilyInPolyTime_rounds (M : ℕ) : /-- **The time of a step**: a polynomial in the length of the encoded state, plus the time of the decider when it runs on the formula on top of the stack. -/ -theorem exists_computableTidilyInO_step (K α : ℕ) {g : CNF ℕ → Bool} {t : CNF ℕ → ℕ} +private theorem exists_computableTidilyInO_step (K α : ℕ) {g : CNF ℕ → Bool} {t : CNF ℕ → ℕ} (hg : ComputableTidilyInO g encCNF encBool t t) : ∃ d, ComputableTidilyInO (step K α g) encState encState (fun s => ((encState s).length + 1) ^ d + @@ -420,15 +422,15 @@ end PolyTime /-! ### Sizes -/ /-- A bound on the length of the encoded states of the tree. -/ -def nodeBound (K α : ℕ) (φ : CNF ℕ) : ℕ := +private def nodeBound (K α : ℕ) (φ : CNF ℕ) : ℕ := (φ.length + φ.numVars * (K * base K α ^ (2 * K))) * (2 * (K * (2 * (encCNF φ).length + 1)) + 1) /-- A bound on the length of the encoded states of the search. -/ -def stateBound (K α : ℕ) (φ : CNF ℕ) : ℕ := +private def stateBound (K α : ℕ) (φ : CNF ℕ) : ℕ := 2 * ((φ.numVars * (K * base K α ^ (2 * K)) + 1) * (2 * nodeBound K α φ + 1)) + 2 -theorem length_encLiteral_le {φ : CNF ℕ} {D : Clause ℕ} (hD : D ∈ φ) {l : Literal ℕ} +private theorem length_encLiteral_le {φ : CNF ℕ} {D : Clause ℕ} (hD : D ∈ φ) {l : Literal ℕ} (hl : l ∈ D) : (encPair encNat encBool l).length ≤ (encCNF φ).length := (length_le_encList_of_mem _ hl).trans (length_le_encList_of_mem _ hD) @@ -437,7 +439,8 @@ section Sizes variable {k : ℕ} (hkK : k ≤ K) {φ : CNF ℕ} include hK hα hkK -theorem length_encCNF_walk_le {w : List Bool} (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) : +private theorem length_encCNF_walk_le {w : List Bool} + (hw : (rule hK hα).IsNodeWord (rootState hkK φ) w) : (encCNF ((rule hK hα).walk (rootState hkK φ) w).1).length ≤ nodeBound K α φ := by set ψ := (rule hK hα).walk (rootState hkK φ) w refine (length_encList_le _ ψ.1 (b := K * (2 * (encCNF φ).length + 1)) fun C hC => ?_).trans @@ -447,7 +450,7 @@ theorem length_encCNF_walk_le {w : List Bool} (hw : (rule hK hα).IsNodeWord (ro obtain ⟨D, hD, hCD⟩ := exists_of_mem_walk hK hα hkK hw hC exact length_encLiteral_le hD (List.mem_toFinset.mp (hCD (List.mem_toFinset.mpr hl))) -theorem length_encState_le {stk : List {ψ : CNF ℕ // Normalized K ψ}} {acc : Bool} +private theorem length_encState_le {stk : List {ψ : CNF ℕ // Normalized K ψ}} {acc : Bool} (hstk : stk.length ≤ φ.numVars * (K * base K α ^ (2 * K)) + 1) (hmem : ∀ t ∈ stk, ∃ w, (rule hK hα).IsNodeWord (rootState hkK φ) w ∧ (rule hK hα).walk (rootState hkK φ) w = t) : @@ -466,7 +469,7 @@ end Sizes /-! ### The time of the search -/ /-- The time bound of the decider on the leaves of the tree. -/ -noncomputable def leafTime (K α : ℕ) (δ : ℝ) (c e : ℕ) (φ : CNF ℕ) : ℕ := +private noncomputable def leafTime (K α : ℕ) (δ : ℝ) (c e : ℕ) (φ : CNF ℕ) : ℕ := ⌈(c : ℝ) * (2 ^ (δ * ((occBound K α * φ.numVars + 1 : ℕ) : ℝ)) * ((nodeBound K α φ : ℝ) + 1) ^ e) + c⌉₊ @@ -475,7 +478,7 @@ include hK hα in a round: a polynomial in the length of the encoded states (`stateBound`), plus the time bound of the decider on the leaves (`leafTime`), plus the cost of the counter; and within polynomial time for the start. -/ -theorem exists_computableTidilyInO_search {k M : ℕ} (hkK : k ≤ K) (hM : LeafBound K α M) +private theorem exists_computableTidilyInO_search {k M : ℕ} (hkK : k ≤ K) (hM : LeafBound K α M) {g : CNF ℕ → Bool} {t : CNF ℕ → ℕ} (hg : ComputableTidilyInO g encCNF encBool t t) {δ : ℝ} (hδ : 0 ≤ δ) {c e : ℕ} (ht : ∀ ψ : CNF ℕ, (t ψ : ℝ) ≤ c * (2 ^ (δ * ψ.length) * ((encCNF ψ).length + 1) ^ e) + c) : diff --git a/Complexity/Computability/Complexity/HardnessEncoding/PolyTime.lean b/Complexity/Computability/Complexity/HardnessEncoding/PolyTime.lean index 63e249913..995ec10dd 100644 --- a/Complexity/Computability/Complexity/HardnessEncoding/PolyTime.lean +++ b/Complexity/Computability/Complexity/HardnessEncoding/PolyTime.lean @@ -55,7 +55,7 @@ open Turing.MultiTapeTM ComputableTidilyInPolyTime Cslib.AffineDisperser /-! ### Field arithmetic -/ /-- The multiplication table of the power basis, from the coefficient list of the modulus. -/ -theorem computableTidilyInPolyTime_powerMulTable : +private theorem computableTidilyInPolyTime_powerMulTable : ComputableTidilyInPolyTime powerMulTable encBits encTable := by unfold powerMulTable have := computableTidilyInPolyTime_powerTable @@ -84,7 +84,7 @@ private def lagrangeStep (par : (List (List (List Bool)) × ℕ) × (List Bool /-- **The Lagrange numerator is polynomial-time**, uniformly in the table, the width, the nodes, the node and the point: a fold over the nodes whose states are field elements. -/ -theorem computableTidilyInPolyTime_lagrangeNum : ComputableTidilyInPolyTime +private theorem computableTidilyInPolyTime_lagrangeNum : ComputableTidilyInPolyTime (fun p : ((List (List (List Bool)) × ℕ) × List (List Bool)) × (List Bool × List Bool) => lagrangeNum p.1.1.1 p.1.1.2 p.1.2 p.2.1 p.2.2) (encPair (encPair (encPair encTable encUnary) (encList encBits)) (encPair encBits encBits)) diff --git a/Complexity/Computability/Complexity/HardnessEncoding/Program.lean b/Complexity/Computability/Complexity/HardnessEncoding/Program.lean index 93281c7f5..eda38186a 100644 --- a/Complexity/Computability/Complexity/HardnessEncoding/Program.lean +++ b/Complexity/Computability/Complexity/HardnessEncoding/Program.lean @@ -171,17 +171,17 @@ theorem isMulTable_fieldTable {w : ℕ} (hw : w ≠ 0) : IsMulTable (𝔅 hw) (f variable {w : ℕ} /-- The element with given coordinates in the power basis is the element with these bits. -/ -theorem fieldOfBits_basis (hw : w ≠ 0) (a : List Bool) : +private theorem fieldOfBits_basis (hw : w ≠ 0) (a : List Bool) : fieldOfBits (𝔅 hw) a = (BinaryField.equivBits hw).symm fun j => a.getD j false := by rw [fieldOfBits, BinaryField.equivBits_symm_apply] /-- The bits of the element with given coordinates. -/ -theorem equivBits_fieldOfBits (hw : w ≠ 0) (a : List Bool) (j : Fin w) : +private theorem equivBits_fieldOfBits (hw : w ≠ 0) (a : List Bool) (j : Fin w) : BinaryField.equivBits hw (fieldOfBits (𝔅 hw) a) j = a.getD j false := by rw [BinaryField.equivBits_apply, repr_fieldOfBits, RingEquiv.apply_symm_apply] /-- The coordinates `[true]` are those of `1`. -/ -theorem fieldOfBits_one (hw : w ≠ 0) : fieldOfBits (𝔅 hw) [true] = 1 := by +private theorem fieldOfBits_one (hw : w ≠ 0) : fieldOfBits (𝔅 hw) [true] = 1 := by rw [fieldOfBits, Fintype.sum_eq_single ⟨0, Nat.pos_of_ne_zero hw⟩] · simp [BinaryField.basis_apply, bitEquiv_symm_true] · intro u hu @@ -190,13 +190,13 @@ theorem fieldOfBits_one (hw : w ≠ 0) : fieldOfBits (𝔅 hw) [true] = 1 := by simp [hk, bitEquiv_symm_false] /-- Addition in coordinates: `listXor w [a, b]` has the sum of the coordinates. -/ -theorem fieldOfBits_listXor_pair (hw : w ≠ 0) (a b : List Bool) : +private theorem fieldOfBits_listXor_pair (hw : w ≠ 0) (a b : List Bool) : fieldOfBits (𝔅 hw) (listXor w [a, b]) = fieldOfBits (𝔅 hw) a + fieldOfBits (𝔅 hw) b := by rw [fieldOfBits_listXor] simp /-- In a field of `2 ^ w` elements, `w ≥ 2`, the inverse is the power `2 ^ w - 2`. -/ -theorem fieldOfBits_fieldInv (hw : 2 ≤ w) (a : List Bool) : +private theorem fieldOfBits_fieldInv (hw : 2 ≤ w) (a : List Bool) : fieldOfBits (𝔅 (by omega : w ≠ 0)) (fieldInv (fieldTable w) w a) = (fieldOfBits (𝔅 (by omega : w ≠ 0)) a)⁻¹ := by have hw0 : w ≠ 0 := by omega @@ -229,7 +229,7 @@ theorem fieldOfBits_fieldInv (hw : 2 ≤ w) (a : List Bool) : /-! ### Correctness -/ /-- The embedded bit string is the element with its bits as coordinates. -/ -theorem embed_eq_fieldOfBits (hw : w ≠ 0) {b : ℕ} (hbw : b ≤ w) (a : BitString b) : +private theorem embed_eq_fieldOfBits (hw : w ≠ 0) {b : ℕ} (hbw : b ≤ w) (a : BitString b) : BinaryField.embed hw hbw a = fieldOfBits (𝔅 hw) (List.ofFn a) := by rw [BinaryField.embed_apply, fieldOfBits_basis] congr 1 @@ -246,7 +246,7 @@ theorem fieldOfBits_ofFn (hw : w ≠ 0) (v : BitString w) : simp [List.getD_eq_getElem?_getD] /-- The numerator of a Lagrange basis polynomial: the product of `t - a'` over the other nodes. -/ -theorem fieldOfBits_lagrangeNum (hw : w ≠ 0) {b : ℕ} (hbw : b ≤ w) (a : BitString b) +private theorem fieldOfBits_lagrangeNum (hw : w ≠ 0) {b : ℕ} (hbw : b ≤ w) (a : BitString b) (t : List Bool) : fieldOfBits (𝔅 hw) (lagrangeNum (fieldTable w) w (BitString.enumList b) (List.ofFn a) t) = ∏ a' ∈ univ.erase a, (fieldOfBits (𝔅 hw) t - BinaryField.embed hw hbw a') := by @@ -280,7 +280,7 @@ theorem fieldOfBits_lagrangeVal (hw : 2 ≤ w) {b : ℕ} (hbw : b ≤ w) (a : Bi /-- **A term of the extension**: `termVal` computes the product over the blocks of `z` of the Lagrange basis polynomials at the coordinates of the point. -/ -theorem fieldOfBits_termVal (hw : 2 ≤ w) {M b : ℕ} (hbw : b ≤ w) (xs : List (List Bool)) +private theorem fieldOfBits_termVal (hw : 2 ≤ w) {M b : ℕ} (hbw : b ≤ w) (xs : List (List Bool)) (z : BitString (M * b)) : fieldOfBits (𝔅 (by omega : w ≠ 0)) (termVal (fieldTable w) w b M (BitString.enumList b) xs (List.ofFn z)) = diff --git a/Complexity/Computability/Complexity/Parameterized/VertexCover.lean b/Complexity/Computability/Complexity/Parameterized/VertexCover.lean index 0fc4dfbfa..ca8324323 100644 --- a/Complexity/Computability/Complexity/Parameterized/VertexCover.lean +++ b/Complexity/Computability/Complexity/Parameterized/VertexCover.lean @@ -99,7 +99,7 @@ def branchStep (G : Graph) (C : List ℕ) (b : Bool) : List ℕ := def foldBranch (G : Graph) (bs : List Bool) : List ℕ := bs.foldl (branchStep G) [] -theorem foldBranch_append_singleton (G : Graph) (bs : List Bool) (b : Bool) : +private theorem foldBranch_append_singleton (G : Graph) (bs : List Bool) (b : Bool) : foldBranch G (bs ++ [b]) = branchStep G (foldBranch G bs) b := by simp [foldBranch] @@ -144,7 +144,7 @@ private theorem headD_mem_uncoveredEdges {G : Graph} {C : List ℕ} | nil => simp [hle] at h | cons e es => simp -theorem mem_of_mem_branchStep {G : Graph} {C : List ℕ} {b : Bool} (hC : ∀ v ∈ C, v ∈ G.1) : +private theorem mem_of_mem_branchStep {G : Graph} {C : List ℕ} {b : Bool} (hC : ∀ v ∈ C, v ∈ G.1) : ∀ v ∈ branchStep G C b, v ∈ G.1 := by unfold branchStep cases h : isCover G C @@ -156,13 +156,13 @@ theorem mem_of_mem_branchStep {G : Graph} {C : List ℕ} {b : Bool} (hC : ∀ v · exact hC v hv · simpa using hC -theorem length_branchStep_le (G : Graph) (C : List ℕ) (b : Bool) : +private theorem length_branchStep_le (G : Graph) (C : List ℕ) (b : Bool) : (branchStep G C b).length ≤ C.length + 1 := by unfold branchStep split_ifs <;> simp /-- Every vertex added along a search-tree path is a declared vertex of `G`. -/ -theorem mem_of_mem_foldBranch (G : Graph) (bs : List Bool) : +private theorem mem_of_mem_foldBranch (G : Graph) (bs : List Bool) : ∀ v ∈ foldBranch G bs, v ∈ G.1 := by induction bs using List.reverseRecOn with | nil => simp [foldBranch] @@ -171,7 +171,7 @@ theorem mem_of_mem_foldBranch (G : Graph) (bs : List Bool) : exact mem_of_mem_branchStep ih /-- A search-tree path of length `|bs|` picks at most `|bs|` vertices. -/ -theorem length_foldBranch_le (G : Graph) (bs : List Bool) : +private theorem length_foldBranch_le (G : Graph) (bs : List Bool) : (foldBranch G bs).length ≤ bs.length := by induction bs using List.reverseRecOn with | nil => simp [foldBranch] @@ -228,7 +228,7 @@ private theorem exists_foldBranch_subset (G : Graph) {S : Finset ℕ} /-- If `G` has a vertex cover of at most `m` vertices, some branching word `bs` of length `m` produces a cover. -/ -theorem exists_isCover_foldBranch {G : Graph} {S : Finset ℕ} +private theorem exists_isCover_foldBranch {G : Graph} {S : Finset ℕ} (hS : ∀ u ∈ G.1, ∀ v ∈ G.1, G.toSimpleGraph.Adj u v → u ∈ S ∨ v ∈ S) {m : ℕ} (hm : S.card ≤ m) : ∃ bs : List Bool, bs.length = m ∧ isCover G (foldBranch G bs) = true := by @@ -280,7 +280,7 @@ def cap (x : Graph × ℕ) : ℕ := theorem cap_eq (x : Graph × ℕ) : cap x = min x.1.1.toFinset.card x.2 := by rw [cap, Graph.length_distinctVertices] -theorem cap_le_length (x : Graph × ℕ) : cap x ≤ (encGraph x.1).length := +private theorem cap_le_length (x : Graph × ℕ) : cap x ≤ (encGraph x.1).length := (Nat.min_le_left _ _).trans x.1.length_distinctVertices_le theorem cap_le_snd (x : Graph × ℕ) : cap x ≤ x.2 := @@ -291,7 +291,7 @@ in unary, the number of the next root-to-leaf path to try, and whether a cover h abbrev State : Type := ((Graph × ℕ) × ℕ) × (ℕ × Bool) /-- States encoded as framed tuples, with the capped depth in unary. -/ -abbrev encState : State ↪ List Bool := +private abbrev encState : State ↪ List Bool := encPair (encPair (encPair encGraph encNat) encUnary) (encPair encNat encBool) /-- Try the next numbered path in the bounded search tree. -/ @@ -311,7 +311,7 @@ length `cap x` and check that `k ≤ |V|` (`cap x = k`). -/ def search (x : Graph × ℕ) : Bool := finish (step^[2 ^ cap x] (init x)) -theorem iterate_step_init (x : Graph × ℕ) (j : ℕ) : +private theorem iterate_step_init (x : Graph × ℕ) (j : ℕ) : step^[j] (init x) = ((x, cap x), (j, (List.range j).any fun i => isCover x.1 (foldBranch x.1 ((List.range (cap x)).map i.testBit)))) := by @@ -441,7 +441,7 @@ private theorem length_encList_branchStep_le (G : Graph) (C : List ℕ) (b : Boo open ComputableTidilyInPolyTime in /-- Computing the `m` branching bits of path `i` is polynomial-time. -/ -theorem computableTidilyInPolyTime_branchBits : +private theorem computableTidilyInPolyTime_branchBits : ComputableTidilyInPolyTime (fun s : State => (List.range s.1.2).map s.2.1.testBit) encState (encList encBool) := by have heq : (fun s : State => (List.range s.1.2).map s.2.1.testBit) = @@ -458,7 +458,7 @@ theorem computableTidilyInPolyTime_branchBits : open ComputableTidilyInPolyTime in /-- Following a root-to-leaf path in the bounded search tree is polynomial-time. -/ -theorem computableTidilyInPolyTime_foldBranch : +private theorem computableTidilyInPolyTime_foldBranch : ComputableTidilyInPolyTime (fun s : State => foldBranch s.1.1.1 ((List.range s.1.2).map s.2.1.testBit)) encState (encList encNat) := by @@ -472,7 +472,8 @@ theorem computableTidilyInPolyTime_foldBranch : open ComputableTidilyInPolyTime in /-- One step of the search iteration is polynomial-time. -/ -theorem computableTidilyInPolyTime_step : ComputableTidilyInPolyTime step encState encState := by +private theorem computableTidilyInPolyTime_step + : ComputableTidilyInPolyTime step encState encState := by have hcov : ComputableTidilyInPolyTime (fun s : State => isCover s.1.1.1 (foldBranch s.1.1.1 ((List.range s.1.2).map s.2.1.testBit))) encState encBool := @@ -489,20 +490,20 @@ theorem computableTidilyInPolyTime_step : ComputableTidilyInPolyTime step encSta open ComputableTidilyInPolyTime in /-- The initial state of the search is computed in polynomial time. -/ -theorem computableTidilyInPolyTime_init : +private theorem computableTidilyInPolyTime_init : ComputableTidilyInPolyTime init (encPair encGraph encNat) encState := by unfold init fun_prop open ComputableTidilyInPolyTime in /-- The number `2 ^ cap x` of paths is computed in binary in polynomial time. -/ -theorem computableTidilyInPolyTime_count : +private theorem computableTidilyInPolyTime_count : ComputableTidilyInPolyTime (fun x => 2 ^ cap x) (encPair encGraph encNat) encNat := by fun_prop open ComputableTidilyInPolyTime in /-- Extracting the final answer from the search state is polynomial-time. -/ -theorem computableTidilyInPolyTime_finish : +private theorem computableTidilyInPolyTime_finish : ComputableTidilyInPolyTime finish encState encBool := by unfold finish exact bool_and' diff --git a/Complexity/Computability/Complexity/Parameterized/VertexCover/BussKernel.lean b/Complexity/Computability/Complexity/Parameterized/VertexCover/BussKernel.lean index f6eb9d992..c49476f93 100644 --- a/Complexity/Computability/Complexity/Parameterized/VertexCover/BussKernel.lean +++ b/Complexity/Computability/Complexity/Parameterized/VertexCover/BussKernel.lean @@ -141,47 +141,47 @@ theorem noInstance_notMem : noInstance ∉ VertexCover := by simp /-- The neighbours of `v` among the distinct declared vertices. -/ -def neighbors (G : Graph) (v : ℕ) : Finset ℕ := +private def neighbors (G : Graph) (v : ℕ) : Finset ℕ := (G.distinctVertices.filter (G.adjBool v)).toFinset -theorem mem_neighbors {G : Graph} {u v : ℕ} : +private theorem mem_neighbors {G : Graph} {u v : ℕ} : u ∈ neighbors G v ↔ u ∈ G.1 ∧ G.toSimpleGraph.Adj v u := by simp [neighbors, Graph.mem_distinctVertices] -theorem card_neighbors (G : Graph) (v : ℕ) : (neighbors G v).card = degree G v := by +private theorem card_neighbors (G : Graph) (v : ℕ) : (neighbors G v).card = degree G v := by rw [neighbors, List.toFinset_card_of_nodup ((Graph.nodup_distinctVertices G).filter _), degree, List.countP_eq_length_filter] -theorem degree_le_card (G : Graph) (v : ℕ) : degree G v ≤ G.1.toFinset.card := +private theorem degree_le_card (G : Graph) (v : ℕ) : degree G v ≤ G.1.toFinset.card := (List.countP_le_length).trans (Graph.length_distinctVertices G).le variable (x : Graph × ℕ) -theorem mem_high {v : ℕ} : v ∈ high x ↔ v ∈ x.1.1 ∧ isHigh x v = true := by +private theorem mem_high {v : ℕ} : v ∈ high x ↔ v ∈ x.1.1 ∧ isHigh x v = true := by simp [high, Graph.mem_distinctVertices] -theorem mem_low {v : ℕ} : v ∈ low x ↔ v ∈ x.1.1 ∧ isHigh x v = false := by +private theorem mem_low {v : ℕ} : v ∈ low x ↔ v ∈ x.1.1 ∧ isHigh x v = false := by simp [low, Graph.mem_distinctVertices] -theorem mem_active {v : ℕ} : +private theorem mem_active {v : ℕ} : v ∈ active x ↔ v ∈ low x ∧ ∃ u ∈ low x, x.1.toSimpleGraph.Adj v u := by simp [active, isActive] -theorem nodup_high : (high x).Nodup := (Graph.nodup_distinctVertices _).filter _ +private theorem nodup_high : (high x).Nodup := (Graph.nodup_distinctVertices _).filter _ -theorem nodup_low : (low x).Nodup := (Graph.nodup_distinctVertices _).filter _ +private theorem nodup_low : (low x).Nodup := (Graph.nodup_distinctVertices _).filter _ -theorem nodup_active : (active x).Nodup := (nodup_low x).filter _ +private theorem nodup_active : (active x).Nodup := (nodup_low x).filter _ -theorem length_active_le_length_low : (active x).length ≤ (low x).length := +private theorem length_active_le_length_low : (active x).length ≤ (low x).length := List.length_filter_le _ _ -theorem length_high_add_length_low : +private theorem length_high_add_length_low : (high x).length + (low x).length = x.1.1.toFinset.card := by rw [← Graph.length_distinctVertices] exact (List.length_eq_length_filter_add _).symm -theorem length_active_le_numVertices : (active x).length ≤ numVertices x := +private theorem length_active_le_numVertices : (active x).length ≤ numVertices x := le_min (length_active_le_length_low x) (Nat.le_add_right _ _) variable {x} @@ -201,7 +201,7 @@ theorem mem_of_isHigh {S : Finset ℕ} simp only [isHigh, decide_eq_true_eq, cap_eq] at hhigh omega -theorem length_high_le_card {S : Finset ℕ} +private theorem length_high_le_card {S : Finset ℕ} (hS : ∀ u ∈ x.1.1, ∀ v ∈ x.1.1, x.1.toSimpleGraph.Adj u v → u ∈ S ∨ v ∈ S) (hcard : S.card ≤ x.2) : (high x).length ≤ S.card := by rw [← List.toFinset_card_of_nodup (nodup_high x)] @@ -239,7 +239,7 @@ theorem length_active_le {S : Finset ℕ} _ ≤ x.2 * (x.2 + 1) := by nlinarith /-- Every instance of `VertexCover` passes the tests of the kernel. -/ -theorem accept_of_mem (hx : x ∈ VertexCover) : accept x = true := by +private theorem accept_of_mem (hx : x ∈ VertexCover) : accept x = true := by obtain ⟨G, k⟩ := x obtain ⟨hk, S, -, hS, hcard⟩ := mem_VertexCover_iff_exists_card_le.1 hx have hcap : cap (G, k) = k := by rw [cap_eq]; exact min_eq_right hk @@ -248,7 +248,8 @@ theorem accept_of_mem (hx : x ∈ VertexCover) : accept x = true := by simp only [accept, hcap, Bool.and_eq_true, decide_eq_true_eq, true_and] exact ⟨h₁.trans hcard, h₂⟩ -theorem mem_edges {i j : ℕ} : (i, j) ∈ edges x ↔ i < (active x).length ∧ j < (active x).length ∧ +private theorem mem_edges {i j : ℕ} : (i, j) ∈ edges x ↔ i < (active x).length ∧ j < + (active x).length ∧ x.1.toSimpleGraph.Adj ((active x).getD i 0) ((active x).getD j 0) := by simp only [edges, List.mem_flatMap, List.mem_range, List.mem_map, List.mem_filter, Graph.adjBool_eq_true_iff, Prod.mk.injEq] @@ -258,7 +259,7 @@ theorem mem_edges {i j : ℕ} : (i, j) ∈ edges x ↔ i < (active x).length ∧ · rintro ⟨hi, hj, hadj⟩ exact ⟨i, hi, j, ⟨hj, hadj⟩, rfl, rfl⟩ -theorem graph_adj {i j : ℕ} : (graph x).toSimpleGraph.Adj i j ↔ i ≠ j ∧ +private theorem graph_adj {i j : ℕ} : (graph x).toSimpleGraph.Adj i j ↔ i ≠ j ∧ ((i, j) ∈ edges x ∨ (j, i) ∈ edges x) := by simp [graph, Graph.toSimpleGraph, SimpleGraph.fromRel_adj] @@ -372,9 +373,10 @@ namespace VertexCover.Buss variable (x : Graph × ℕ) -theorem param_le_cap : param x ≤ cap x := Nat.sub_le _ _ +private theorem param_le_cap : param x ≤ cap x := Nat.sub_le _ _ -theorem numVertices_le_of_accept (h : accept x = true) : numVertices x ≤ x.2 * (x.2 + 2) := by +private theorem numVertices_le_of_accept (h : accept x = true) : numVertices x ≤ x.2 * + (x.2 + 2) := by simp only [accept, Bool.and_eq_true, decide_eq_true_eq] at h obtain ⟨⟨hc, -⟩, ha⟩ := h have h₁ := param_le_cap x @@ -382,7 +384,7 @@ theorem numVertices_le_of_accept (h : accept x = true) : numVertices x ≤ x.2 * rw [hc] at h₁ nlinarith -theorem length_edges_le : (edges x).length ≤ (active x).length * (active x).length := by +private theorem length_edges_le : (edges x).length ≤ (active x).length * (active x).length := by rw [edges, List.length_flatMap] refine (List.sum_le_length_nsmul _ (active x).length fun n hn => ?_).trans ?_ · obtain ⟨i, -, rfl⟩ := List.mem_map.1 hn @@ -390,7 +392,7 @@ theorem length_edges_le : (edges x).length ≤ (active x).length * (active x).le exact (List.length_filter_le _ _).trans (List.length_range).le · simp -theorem length_edges_le_of_accept (h : accept x = true) : +private theorem length_edges_le_of_accept (h : accept x = true) : (edges x).length ≤ (x.2 * (x.2 + 1)) * (x.2 * (x.2 + 1)) := by simp only [accept, Bool.and_eq_true, decide_eq_true_eq] at h obtain ⟨⟨hc, -⟩, ha⟩ := h @@ -416,7 +418,7 @@ private theorem size_arith {k K : ℕ} (hK : K ≤ k * (k + 2)) : omega /-- The encoded kernel has length at most `40 (k + 1) ^ 6`. -/ -theorem length_encode_le_of_accept (h : accept x = true) : +private theorem length_encode_le_of_accept (h : accept x = true) : (encPair encGraph encNat (graph x, param x)).length ≤ 40 * (x.2 + 1) ^ 6 := by set K := x.2 * (x.2 + 2) have hV : numVertices x ≤ K := numVertices_le_of_accept x h @@ -618,7 +620,7 @@ theorem computableTidilyInPolyTime_bussKernel : (ComputableTidilyInPolyTime.const _) /-- Buss's kernel has target at most `k`, or `1`. -/ -theorem bussKernel_snd_le (x : Graph × ℕ) : (bussKernel x).2 ≤ max x.2 1 := by +private theorem bussKernel_snd_le (x : Graph × ℕ) : (bussKernel x).2 ≤ max x.2 1 := by unfold bussKernel split_ifs with h · exact le_max_of_le_left ((param_le_cap x).trans (cap_le_snd x)) diff --git a/Complexity/Computability/Complexity/Problems/CircuitSAT.lean b/Complexity/Computability/Complexity/Problems/CircuitSAT.lean index b35b67d08..9343a95c0 100644 --- a/Complexity/Computability/Complexity/Problems/CircuitSAT.lean +++ b/Complexity/Computability/Complexity/Problems/CircuitSAT.lean @@ -91,7 +91,7 @@ theorem isVerifier : IsVerifier (encCircuit 1) Polynomial.X verifier CircuitSAT rw [List.getD_append _ _ _ _ (by simp), List.getD_eq_getElem _ _ (by simp), List.getElem_ofFn] /-- The verifier evaluates the code of the circuit on the first bits of the certificate. -/ -theorem verifier_eq_evalOutput (p : (Σ n, Circuit signature n 1) × List Bool) : +private theorem verifier_eq_evalOutput (p : (Σ n, Circuit signature n 1) × List Bool) : verifier p = evalOutput ((List.range p.1.1).map fun i => p.2.getD i false) p.1.2.code.1 (p.1.2.code.2.headD 0) := by have h : List.ofFn (fun i : Fin p.1.1 => p.2.getD i false) = @@ -153,12 +153,12 @@ def circuitGates (φ : CNF ℕ) : List (Op × List ℕ) := def circuitCode (φ : CNF ℕ) : List (Op × List ℕ) × List ℕ := (circuitGates φ, [φ.vars.length + 3 * (circuitSteps φ).length + 2]) -theorem length_circuitBlock (p i : ℕ) (b e : Bool) : (circuitBlock p i b e).length = 3 := by +private theorem length_circuitBlock (p i : ℕ) (b e : Bool) : (circuitBlock p i b e).length = 3 := by unfold circuitBlock split <;> rfl /-- The circuit of a formula has three gates for each instruction, and three more. -/ -theorem length_circuitGates (φ : CNF ℕ) : +private theorem length_circuitGates (φ : CNF ℕ) : (circuitGates φ).length = 3 * (circuitSteps φ).length + 3 := by rw [circuitGates, List.length_append, List.length_flatMap] simp only [length_circuitBlock, List.map_const', List.sum_replicate, List.length_zipIdx, @@ -166,7 +166,7 @@ theorem length_circuitGates (φ : CNF ℕ) : simp only [List.length_cons, List.length_nil] omega -theorem isCodeFrom_circuitBlock {n k i : ℕ} (b e : Bool) (hi : e = false → i < n) : +private theorem isCodeFrom_circuitBlock {n k i : ℕ} (b e : Bool) (hi : e = false → i < n) : Program.IsCodeFrom signature n (3 * k + 3) (circuitBlock (n + 3 * k) i b e) := by cases e · have hi := hi rfl @@ -179,7 +179,7 @@ theorem isCodeFrom_circuitBlock {n k i : ℕ} (b e : Bool) (hi : e = false → i (intro _ h; simp only [List.mem_cons, List.not_mem_nil, or_false] at h; rcases h with rfl | rfl <;> omega) -theorem isCodeFrom_circuitBlocks (φ : CNF ℕ) (steps : List (Literal ℕ × Bool)) (k : ℕ) +private theorem isCodeFrom_circuitBlocks (φ : CNF ℕ) (steps : List (Literal ℕ × Bool)) (k : ℕ) (h : ∀ s ∈ steps, s.2 = false → s.1.1 ∈ φ.vars) : Program.IsCodeFrom signature φ.vars.length (3 * k + 3) ((steps.zipIdx k).flatMap fun s => circuitBlock (φ.vars.length + 3 * s.2) (φ.vars.idxOf s.1.1.1) s.1.1.2 s.1.2) := by @@ -194,7 +194,7 @@ theorem isCodeFrom_circuitBlocks (φ : CNF ℕ) (steps : List (Literal ℕ × Bo split_ifs <;> simpa [Nat.mul_add, Nat.add_assoc] using this /-- Every literal instruction reads a variable of the formula. -/ -theorem mem_vars_of_mem_circuitSteps {φ : CNF ℕ} {s : Literal ℕ × Bool} +private theorem mem_vars_of_mem_circuitSteps {φ : CNF ℕ} {s : Literal ℕ × Bool} (hs : s ∈ circuitSteps φ) (he : s.2 = false) : s.1.1 ∈ φ.vars := by obtain ⟨c, hc, hs⟩ := List.mem_flatMap.1 hs rcases List.mem_append.1 hs with hs | hs @@ -219,7 +219,7 @@ theorem isSome_ofCode_circuitCode (φ : CNF ℕ) : def toCircuit (φ : CNF ℕ) : Σ n, Circuit signature n 1 := ⟨φ.vars.length, (Circuit.ofCode _ 1 (circuitCode φ)).get (isSome_ofCode_circuitCode φ)⟩ -theorem code_toCircuit (φ : CNF ℕ) : (toCircuit φ).2.code = circuitCode φ := +private theorem code_toCircuit (φ : CNF ℕ) : (toCircuit φ).2.code = circuitCode φ := Circuit.code_of_ofCode_eq_some (Option.some_get _).symm /-! ### Correctness of the circuit of a formula -/ @@ -346,14 +346,15 @@ theorem toCircuit_mem_CircuitSAT_iff (φ : CNF ℕ) : toCircuit φ ∈ CircuitSA open ComputableTidilyInPolyTime /-- Listing the instructions of the circuit of a formula is polynomial-time. -/ -theorem computableTidilyInPolyTime_circuitSteps : ComputableTidilyInPolyTime circuitSteps encCNF +private theorem computableTidilyInPolyTime_circuitSteps + : ComputableTidilyInPolyTime circuitSteps encCNF (encList (encPair (encPair encNat encBool) encBool)) := by unfold circuitSteps encCNF fun_prop /-- Writing the block of an instruction is polynomial-time, from the position `p` and the input `i` in unary; the gates use their binary numbers. -/ -theorem computableTidilyInPolyTime_circuitBlock : +private theorem computableTidilyInPolyTime_circuitBlock : ComputableTidilyInPolyTime (fun q : ((ℕ × ℕ) × Bool) × Bool => circuitBlock q.1.1.1 q.1.1.2 q.1.2 q.2) (encPair (encPair (encPair encUnary encUnary) encBool) encBool) (encList encGate) := by @@ -383,7 +384,7 @@ theorem computableTidilyInPolyTime_circuitBlock : (cons' (hgate .and (cons' (hp 2) (cons' (hp 2) (hnil _)))) (hnil _))) /-- Writing the gates of the circuit of a formula is polynomial-time. -/ -theorem computableTidilyInPolyTime_circuitGates : +private theorem computableTidilyInPolyTime_circuitGates : ComputableTidilyInPolyTime circuitGates encCNF (encList encGate) := by have hsteps := computableTidilyInPolyTime_circuitSteps have hvars := SAT.computableTidilyInPolyTime_vars @@ -398,7 +399,7 @@ theorem computableTidilyInPolyTime_circuitGates : /-- Building the circuit of a formula is polynomial-time, from the encoding `encCNF` of formulas to the binary encoding `encCircuit 1` of circuits. -/ -theorem computableTidilyInPolyTime_toCircuit : +private theorem computableTidilyInPolyTime_toCircuit : ComputableTidilyInPolyTime toCircuit encCNF (encCircuit 1) := by have hg := computableTidilyInPolyTime_circuitGates have hs := computableTidilyInPolyTime_circuitSteps diff --git a/Complexity/Computability/Complexity/Problems/Coloring.lean b/Complexity/Computability/Complexity/Problems/Coloring.lean index c5610687d..269c5ade9 100644 --- a/Complexity/Computability/Complexity/Problems/Coloring.lean +++ b/Complexity/Computability/Complexity/Problems/Coloring.lean @@ -249,7 +249,7 @@ def toThreeColoring (φ : CNF ℕ) : Graph := /-! ### Correctness of the reduction -/ /-- No edge of the gadget graph is a self-loop. -/ -theorem ne_of_mem_coloringEdges {φ : CNF ℕ} {e : ℕ × ℕ} (he : e ∈ coloringEdges φ) : +private theorem ne_of_mem_coloringEdges {φ : CNF ℕ} {e : ℕ × ℕ} (he : e ∈ coloringEdges φ) : e.1 ≠ e.2 := by simp only [coloringEdges, clauseEdges, stageEdges, variableEdges, List.mem_append, List.mem_flatMap, List.mem_cons, List.not_mem_nil, or_false] at he diff --git a/Complexity/Computability/Complexity/Problems/ExactThreeSAT.lean b/Complexity/Computability/Complexity/Problems/ExactThreeSAT.lean index 8cbd9f9f3..59ae37eac 100644 --- a/Complexity/Computability/Complexity/Problems/ExactThreeSAT.lean +++ b/Complexity/Computability/Complexity/Problems/ExactThreeSAT.lean @@ -66,7 +66,7 @@ def padClause (c : Clause ℕ) : Clause ℕ := else if c.length = 2 then c ++ [c.headD (0, true)] else c /-- Padding a clause neither adds nor removes literals. -/ -theorem mem_padClause (c : Clause ℕ) (l : Literal ℕ) : l ∈ padClause c ↔ l ∈ c := by +private theorem mem_padClause (c : Clause ℕ) (l : Literal ℕ) : l ∈ padClause c ↔ l ∈ c := by rcases c with _ | ⟨a, _ | ⟨b, _ | ⟨d, t⟩⟩⟩ · simp [padClause] · simp [padClause] @@ -77,7 +77,7 @@ theorem mem_padClause (c : Clause ℕ) (l : Literal ℕ) : l ∈ padClause c ↔ · simp [padClause] /-- Padding a clause does not shorten it. -/ -theorem length_le_length_padClause (c : Clause ℕ) : c.length ≤ (padClause c).length := by +private theorem length_le_length_padClause (c : Clause ℕ) : c.length ≤ (padClause c).length := by unfold padClause split_ifs <;> simp diff --git a/Complexity/Computability/Complexity/Problems/GraphIsomorphism.lean b/Complexity/Computability/Complexity/Problems/GraphIsomorphism.lean index 761638c5c..0081a25d8 100644 --- a/Complexity/Computability/Complexity/Problems/GraphIsomorphism.lean +++ b/Complexity/Computability/Complexity/Problems/GraphIsomorphism.lean @@ -74,7 +74,7 @@ theorem vertexEquiv_apply (G : Graph) (i : Fin G.distinctVertices.length) : (G.vertexEquiv i : ℕ) = G.distinctVertices.getD i 0 := by simp [vertexEquiv, List.Nodup.getEquiv, List.getD_eq_getElem?_getD] -theorem induced_adj_vertexEquiv (G : Graph) (i j : Fin G.distinctVertices.length) : +private theorem induced_adj_vertexEquiv (G : Graph) (i j : Fin G.distinctVertices.length) : G.induced.Adj (G.vertexEquiv i) (G.vertexEquiv j) ↔ G.adjIndex i j = true := by rw [induced, SimpleGraph.induce_adj, adjIndex, adjBool_eq_true_iff, vertexEquiv_apply, vertexEquiv_apply] diff --git a/Complexity/Computability/Complexity/Problems/Hamiltonian/Undirected.lean b/Complexity/Computability/Complexity/Problems/Hamiltonian/Undirected.lean index c88f5a145..41281320b 100644 --- a/Complexity/Computability/Complexity/Problems/Hamiltonian/Undirected.lean +++ b/Complexity/Computability/Complexity/Problems/Hamiltonian/Undirected.lean @@ -92,7 +92,7 @@ private theorem eq_of_idxOf_eq {G : Graph} {u v : ℕ} (hv : v ∈ G.1) ((List.idxOf_inj hv).1 h.symm).symm /-- Gadget vertices of a declared vertex determine the vertex and the position in the gadget. -/ -theorem splitVertex_eq_splitVertex_iff_of_mem {G : Graph} {u v r r' : ℕ} (hv : v ∈ G.1) : +private theorem splitVertex_eq_splitVertex_iff_of_mem {G : Graph} {u v r r' : ℕ} (hv : v ∈ G.1) : G.splitVertex u r = G.splitVertex v r' ↔ u = v ∧ r = r' := by rw [splitVertex_eq_splitVertex_iff] exact ⟨fun h => ⟨eq_of_idxOf_eq hv h.1, h.2⟩, fun h => ⟨h.1 ▸ rfl, h.2⟩⟩ diff --git a/Complexity/Computability/Complexity/Problems/IndependentSet.lean b/Complexity/Computability/Complexity/Problems/IndependentSet.lean index d5b2d197b..280c1d742 100644 --- a/Complexity/Computability/Complexity/Problems/IndependentSet.lean +++ b/Complexity/Computability/Complexity/Problems/IndependentSet.lean @@ -272,12 +272,12 @@ theorem Occurrence.Conflict.symm {o o' : Occurrence} (h : o.Conflict o') : o'.Co · exact Or.inl ⟨h₁.symm, h₂.symm⟩ · exact Or.inr ⟨h₁.symm, h₂.symm⟩ -theorem Occurrence.Conflict.ne {o o' : Occurrence} (h : o.Conflict o') : o ≠ o' := by +private theorem Occurrence.Conflict.ne {o o' : Occurrence} (h : o.Conflict o') : o ≠ o' := by rintro rfl rcases h with ⟨-, h⟩ | ⟨-, h⟩ <;> exact h rfl /-- An occurrence is determined by its vertex. -/ -theorem vertex_injOn {φ : CNF ℕ} {o o' : Occurrence} (ho : o ∈ occurrences φ) +private theorem vertex_injOn {φ : CNF ℕ} {o o' : Occurrence} (ho : o ∈ occurrences φ) (ho' : o' ∈ occurrences φ) (h : o.vertex = o'.vertex) : o = o' := by obtain ⟨i, j, l⟩ := o obtain ⟨i', j', l'⟩ := o' diff --git a/Complexity/Computability/Complexity/Problems/SubsetSum.lean b/Complexity/Computability/Complexity/Problems/SubsetSum.lean index 28f8ee41b..0b6e55e0e 100644 --- a/Complexity/Computability/Complexity/Problems/SubsetSum.lean +++ b/Complexity/Computability/Complexity/Problems/SubsetSum.lean @@ -220,7 +220,7 @@ theorem nodup_distinctVars : (distinctVars φ).Nodup := by rw [← hu.2, ← hv.2] /-- The variable of every literal of `φ` is listed in `distinctVars φ`. -/ -theorem mem_distinctVars_of_mem {j : ℕ} {l : Literal ℕ} (hl : l ∈ φ.getD j []) : +private theorem mem_distinctVars_of_mem {j : ℕ} {l : Literal ℕ} (hl : l ∈ φ.getD j []) : l.1 ∈ distinctVars φ := by refine mem_distinctVars_of_mem_vars ?_ rcases Nat.lt_or_ge j φ.length with hj | hj @@ -236,7 +236,7 @@ theorem covers_eq_true_iff {i : ℕ} {b : Bool} {j : ℕ} : simp [covers] /-- A clause covers at most as many literal numbers as it has literals. -/ -theorem card_filter_covers_le (A : Finset (ℕ × Bool)) (j : ℕ) : +private theorem card_filter_covers_le (A : Finset (ℕ × Bool)) (j : ℕ) : #{a ∈ A | covers φ a.1 a.2 j} ≤ (φ.getD j []).length := by classical calc #{a ∈ A | covers φ a.1 a.2 j} @@ -255,7 +255,7 @@ private theorem card_filter_fst_le (A : Finset (ℕ × Bool)) (i : ℕ) : #{a _ ≤ 2 := card_le_two /-- The positions of the digits one of a literal number. -/ -theorem mem_literalDigits {i : ℕ} {b : Bool} {p : ℕ} : +private theorem mem_literalDigits {i : ℕ} {b : Bool} {p : ℕ} : p ∈ literalDigits φ i b ↔ p = i ∨ ∃ j < φ.length, covers φ i b j = true ∧ p = (distinctVars φ).length + j := by simp only [literalDigits, List.mem_cons, List.mem_map, List.mem_filter, List.mem_range] @@ -267,7 +267,7 @@ theorem mem_literalDigits {i : ℕ} {b : Bool} {p : ℕ} : · exact Or.inl h · exact Or.inr ⟨j, ⟨hj, hc⟩, rfl⟩ -theorem nodup_literalDigits {i : ℕ} (hi : i < (distinctVars φ).length) (b : Bool) : +private theorem nodup_literalDigits {i : ℕ} (hi : i < (distinctVars φ).length) (b : Bool) : (literalDigits φ i b).Nodup := by refine List.nodup_cons.2 ⟨fun h => ?_, ((List.nodup_range).filter _).map (fun _ _ h => Nat.add_left_cancel h)⟩ @@ -278,27 +278,28 @@ theorem nodup_literalDigits {i : ℕ} (hi : i < (distinctVars φ).length) (b : B abbrev Item : Type := (ℕ × Bool) ⊕ (ℕ × Bool) /-- The digit positions of an item. -/ -def itemDigits (φ : CNF ℕ) : Item → List ℕ := +private def itemDigits (φ : CNF ℕ) : Item → List ℕ := Sum.elim (fun a => literalDigits φ a.1 a.2) fun c => [(distinctVars φ).length + c.1] /-- The items of the digit construction, in the order of `digitNumbers`. -/ -def items (φ : CNF ℕ) : List Item := +private def items (φ : CNF ℕ) : List Item := ((List.range (distinctVars φ).length).flatMap fun i => [.inl (i, true), .inl (i, false)]) ++ (List.range φ.length).flatMap fun j => [.inr (j, true), .inr (j, false)] -theorem digitNumbers_eq_map : digitNumbers φ = (items φ).map fun x => octal (itemDigits φ x) := by +private theorem digitNumbers_eq_map : digitNumbers φ = (items φ).map fun x => octal + (itemDigits φ x) := by simp [digitNumbers, items, List.map_flatMap, itemDigits, octal] /-- All items, as a finite set. -/ -def itemSet (φ : CNF ℕ) : Finset Item := +private def itemSet (φ : CNF ℕ) : Finset Item := (range (distinctVars φ).length ×ˢ univ).disjSum (range φ.length ×ˢ univ) -theorem mem_items {x : Item} : x ∈ items φ ↔ x ∈ itemSet φ := by +private theorem mem_items {x : Item} : x ∈ items φ ↔ x ∈ itemSet φ := by rcases x with ⟨i, b⟩ | ⟨j, c⟩ · cases b <;> simp [items, itemSet] · cases c <;> simp [items, itemSet] -theorem nodup_items : (items φ).Nodup := by +private theorem nodup_items : (items φ).Nodup := by refine List.Nodup.append ?_ ?_ ?_ · refine List.nodup_flatMap.2 ⟨fun i _ => by simp, ?_⟩ exact List.nodup_range.pairwise_of_forall_ne fun i _ i' _ h => by @@ -309,16 +310,16 @@ theorem nodup_items : (items φ).Nodup := by · simp [List.disjoint_left] /-- The digit positions of an item, as a finite set. -/ -def itemCol (φ : CNF ℕ) (x : Item) : Finset ℕ := (itemDigits φ x).toFinset +private def itemCol (φ : CNF ℕ) (x : Item) : Finset ℕ := (itemDigits φ x).toFinset -theorem octal_itemDigits {x : Item} (hx : x ∈ itemSet φ) : +private theorem octal_itemDigits {x : Item} (hx : x ∈ itemSet φ) : octal (itemDigits φ x) = ∑ p ∈ itemCol φ x, 8 ^ p := by rw [itemCol, List.sum_toFinset _ ?_, octal] rcases x with a | c · exact nodup_literalDigits (by simpa [itemSet] using hx) a.2 · simp [itemDigits] -theorem itemCol_subset {x : Item} (hx : x ∈ itemSet φ) : +private theorem itemCol_subset {x : Item} (hx : x ∈ itemSet φ) : itemCol φ x ⊆ range ((distinctVars φ).length + φ.length) := by intro p hp rw [itemCol, List.mem_toFinset] at hp @@ -331,7 +332,7 @@ theorem itemCol_subset {x : Item} (hx : x ∈ itemSet φ) : lia /-- Membership of a variable position in the digits of a literal number. -/ -theorem mem_itemCol_inl_of_lt {a : ℕ × Bool} {i : ℕ} (hi : i < (distinctVars φ).length) : +private theorem mem_itemCol_inl_of_lt {a : ℕ × Bool} {i : ℕ} (hi : i < (distinctVars φ).length) : i ∈ itemCol φ (.inl a) ↔ a.1 = i := by rw [itemCol, List.mem_toFinset, itemDigits, Sum.elim_inl] refine ⟨fun h => ?_, fun h => mem_literalDigits.2 (Or.inl h.symm)⟩ @@ -340,7 +341,7 @@ theorem mem_itemCol_inl_of_lt {a : ℕ × Bool} {i : ℕ} (hi : i < (distinctVar · lia /-- Membership of a clause position in the digits of a literal number. -/ -theorem mem_itemCol_inl_clause {a : ℕ × Bool} (ha : a.1 < (distinctVars φ).length) {j : ℕ} +private theorem mem_itemCol_inl_clause {a : ℕ × Bool} (ha : a.1 < (distinctVars φ).length) {j : ℕ} (hj : j < φ.length) : (distinctVars φ).length + j ∈ itemCol φ (.inl a) ↔ covers φ a.1 a.2 j = true := by rw [itemCol, List.mem_toFinset, itemDigits, Sum.elim_inl, mem_literalDigits] @@ -350,12 +351,12 @@ theorem mem_itemCol_inl_clause {a : ℕ × Bool} (ha : a.1 < (distinctVars φ).l · rwa [Nat.add_left_cancel h] · exact fun h => Or.inr ⟨j, hj, h, rfl⟩ -theorem mem_itemCol_inr {c : ℕ × Bool} {p : ℕ} : +private theorem mem_itemCol_inr {c : ℕ × Bool} {p : ℕ} : p ∈ itemCol φ (.inr c) ↔ p = (distinctVars φ).length + c.1 := by simp [itemCol, itemDigits] /-- Column counts split into literal numbers and slack numbers. -/ -theorem card_filter_disjSum (A B : Finset (ℕ × Bool)) (p : ℕ) : +private theorem card_filter_disjSum (A B : Finset (ℕ × Bool)) (p : ℕ) : #{x ∈ A.disjSum B | p ∈ itemCol φ x} = #{a ∈ A | p ∈ itemCol φ (.inl a)} + #{c ∈ B | p ∈ itemCol φ (.inr c)} := by rw [← card_disjSum] @@ -365,7 +366,7 @@ theorem card_filter_disjSum (A B : Finset (ℕ × Bool)) (p : ℕ) : /-- The target as a number with base-8 digits: one at variable positions, three at clause positions. -/ -theorem digitTarget_eq : +private theorem digitTarget_eq : digitTarget φ = ∑ p ∈ range ((distinctVars φ).length + φ.length), (if p < (distinctVars φ).length then 1 else 3) * 8 ^ p := by have hlist (n : ℕ) (f : ℕ → ℕ) : ((List.range n).map f).sum = ∑ i ∈ range n, f i := by @@ -398,7 +399,8 @@ theorem digitTarget_lt : digitTarget φ < 8 ^ ((distinctVars φ).length + φ.len exact Nat.sum_range_mul_pow_lt fun p _ => by split <;> lia /-- The count at a variable position. -/ -theorem card_filter_var {A B : Finset (ℕ × Bool)} {i : ℕ} (hi : i < (distinctVars φ).length) : +private theorem card_filter_var {A B : Finset (ℕ × Bool)} {i : ℕ} + (hi : i < (distinctVars φ).length) : #{x ∈ A.disjSum B | i ∈ itemCol φ x} = #{a ∈ A | a.1 = i} := by rw [card_filter_disjSum] simp_rw [mem_itemCol_inl_of_lt hi, mem_itemCol_inr] @@ -407,7 +409,7 @@ theorem card_filter_var {A B : Finset (ℕ × Bool)} {i : ℕ} (hi : i < (distin rw [hB, card_empty, Nat.add_zero] /-- The count at a clause position. -/ -theorem card_filter_clause {A B : Finset (ℕ × Bool)} +private theorem card_filter_clause {A B : Finset (ℕ × Bool)} (hA : A ⊆ range (distinctVars φ).length ×ˢ univ) {j : ℕ} (hj : j < φ.length) : #{x ∈ A.disjSum B | (distinctVars φ).length + j ∈ itemCol φ x} = #{a ∈ A | covers φ a.1 a.2 j} + #{c ∈ B | c.1 = j} := by diff --git a/Complexity/Computability/Complexity/Problems/SubsetSum/Mask.lean b/Complexity/Computability/Complexity/Problems/SubsetSum/Mask.lean index c54396025..88bc9585a 100644 --- a/Complexity/Computability/Complexity/Problems/SubsetSum/Mask.lean +++ b/Complexity/Computability/Complexity/Problems/SubsetSum/Mask.lean @@ -79,7 +79,7 @@ theorem exists_maskSelect_eq {s l : List α} (h : s <+ l) : exact ⟨true :: w, by simp [hw], by simp [maskSelect_cons, hs]⟩ /-- Unselected positions beyond the list do not change the selection. -/ -theorem maskSelect_append_replicate_false (l : List α) (w : List Bool) (k : ℕ) : +private theorem maskSelect_append_replicate_false (l : List α) (w : List Bool) (k : ℕ) : maskSelect l (w ++ List.replicate k false) = maskSelect l w := by unfold maskSelect congr 2 diff --git a/Complexity/Computability/Complexity/Problems/TQBF/Closed.lean b/Complexity/Computability/Complexity/Problems/TQBF/Closed.lean index 91c0ec784..136b5e1ab 100644 --- a/Complexity/Computability/Complexity/Problems/TQBF/Closed.lean +++ b/Complexity/Computability/Complexity/Problems/TQBF/Closed.lean @@ -67,7 +67,7 @@ theorem mem_freeVarList {φ : QBF ℕ} {x : ℕ} : x ∈ φ.freeVarList ↔ x | all v φ ih => simp [freeVarList, ih, and_comm] /-- A formula is closed exactly when its list of free variables is empty. -/ -theorem closed_iff_freeVarList_eq_nil {φ : QBF ℕ} : φ.Closed ↔ φ.freeVarList = [] := by +private theorem closed_iff_freeVarList_eq_nil {φ : QBF ℕ} : φ.Closed ↔ φ.freeVarList = [] := by rw [Closed, Finset.eq_empty_iff_forall_notMem, List.eq_nil_iff_forall_not_mem] exact forall_congr' fun x => not_congr mem_freeVarList.symm diff --git a/Complexity/Computability/Complexity/Problems/TSP.lean b/Complexity/Computability/Complexity/Problems/TSP.lean index 8b07fbb53..5a85de6e7 100644 --- a/Complexity/Computability/Complexity/Problems/TSP.lean +++ b/Complexity/Computability/Complexity/Problems/TSP.lean @@ -225,10 +225,11 @@ def toTSP (G : Graph) : List (List ℕ) × ℕ := (cities G).length) /-- The cities of `G` are its declared vertices. -/ -theorem mem_cities {G : Graph} {v : ℕ} : v ∈ cities G ↔ v ∈ G.1 := Graph.mem_distinctVertices +private theorem mem_cities {G : Graph} {v : ℕ} + : v ∈ cities G ↔ v ∈ G.1 := Graph.mem_distinctVertices /-- The cities of `G` are distinct. -/ -theorem nodup_cities (G : Graph) : (cities G).Nodup := G.nodup_distinctVertices +private theorem nodup_cities (G : Graph) : (cities G).Nodup := G.nodup_distinctVertices private theorem dist_map {V : List ℕ} {G : Graph} {i j : ℕ} (hi : i < V.length) (hj : j < V.length) : diff --git a/Complexity/Computability/Complexity/Problems/USTCON.lean b/Complexity/Computability/Complexity/Problems/USTCON.lean index 530c79634..62b6f0ca2 100644 --- a/Complexity/Computability/Complexity/Problems/USTCON.lean +++ b/Complexity/Computability/Complexity/Problems/USTCON.lean @@ -117,7 +117,7 @@ theorem length_matrix : I.matrix.length = I.n * I.n := by simp [matrix] /-- The entry of the row `a` and the column `b` is the bit at `a * n + b` of the matrix. -/ -theorem getD_matrix (a b : Fin I.n) : I.matrix.getD (a * I.n + b) false = I.adj a b := by +private theorem getD_matrix (a b : Fin I.n) : I.matrix.getD (a * I.n + b) false = I.adj a b := by have hlt : (a : ℕ) * I.n + b < I.n * I.n := by have := Nat.mul_le_mul_right I.n (Nat.succ_le_of_lt a.isLt) rw [Nat.succ_mul] at this @@ -140,7 +140,7 @@ def encode : List Bool := (List.replicate I.t true ++ false :: I.matrix)) /-- The number of vertices is at most the length of the encoding. -/ -theorem n_le_length_encode : I.n ≤ I.encode.length := by +private theorem n_le_length_encode : I.n ≤ I.encode.length := by simp [encode] /-- The number of binary digits of `n` is logarithmic in the length of the encoding. -/ diff --git a/Complexity/Computability/DecisionTree/CanonicalTree.lean b/Complexity/Computability/DecisionTree/CanonicalTree.lean index a26c9da90..cbbb3807e 100644 --- a/Complexity/Computability/DecisionTree/CanonicalTree.lean +++ b/Complexity/Computability/DecisionTree/CanonicalTree.lean @@ -67,7 +67,7 @@ theorem mem_freeVars {v : ι} : v ∈ t.freeVars ρ ↔ ∃ b, (v, b) ∈ t ∧ simp [freeVars, Option.isNone_iff_eq_none] /-- A falsified term is false on every input filled from the restriction. -/ -theorem eval_fill_of_falsifiedBy (h : t.FalsifiedBy ρ) (x : ι → Bool) : +private theorem eval_fill_of_falsifiedBy (h : t.FalsifiedBy ρ) (x : ι → Bool) : Term.eval (ρ.fill x) t = false := by obtain ⟨l, hl, hρ⟩ := h rw [Bool.eq_false_iff, ne_eq, Term.eval_eq_true_iff, not_forall] @@ -75,7 +75,7 @@ theorem eval_fill_of_falsifiedBy (h : t.FalsifiedBy ρ) (x : ι → Bool) : /-- A term that is not falsified and has no free variable is true on every input filled from the restriction. -/ -theorem eval_fill_of_freeVars_eq_nil (h : ¬ t.FalsifiedBy ρ) (hV : t.freeVars ρ = []) +private theorem eval_fill_of_freeVars_eq_nil (h : ¬ t.FalsifiedBy ρ) (hV : t.freeVars ρ = []) (x : ι → Bool) : Term.eval (ρ.fill x) t = true := by rw [Term.eval_eq_true_iff] intro l hl @@ -113,7 +113,7 @@ theorem free_of_mem_queried {v : ι} (hv : v ∈ F.queried ρ) : ρ v = none := /-- When nothing is queried, the formula is constant under the restriction: true exactly when some term is not falsified. -/ -theorem eval_fill_of_queried_eq_nil (h : F.queried ρ = []) (x : ι → Bool) : +private theorem eval_fill_of_queried_eq_nil (h : F.queried ρ = []) (x : ι → Bool) : DNF.eval (ρ.fill x) F = (F.firstTerm ρ).isSome := by unfold queried at h cases hf : F.firstTerm ρ with @@ -164,11 +164,11 @@ decreasing_by exact this variable {F} -theorem canonicalTree_of_queried_eq_nil (h : F.queried ρ = []) : +private theorem canonicalTree_of_queried_eq_nil (h : F.queried ρ = []) : F.canonicalTree ρ = leaf (DNF.eval (ρ.fill fun _ => false) F) := by rw [canonicalTree, dite_eq_left h] -theorem canonicalTree_of_queried_ne_nil (h : F.queried ρ ≠ []) : +private theorem canonicalTree_of_queried_ne_nil (h : F.queried ρ ≠ []) : F.canonicalTree ρ = graft (F.queried ρ) (fun a => F.canonicalTree (ρ.assign (F.queried ρ).toFinset a)) fun _ => false := by rw [canonicalTree, dite_eq_right h] diff --git a/Complexity/Computability/DecisionTree/Switching.lean b/Complexity/Computability/DecisionTree/Switching.lean index 495a5d358..330b5e206 100644 --- a/Complexity/Computability/DecisionTree/Switching.lean +++ b/Complexity/Computability/DecisionTree/Switching.lean @@ -80,7 +80,7 @@ def stageCode (t : Term ι) (x : ι → Bool) : List ι → List (ℕ × Bool × variable {t : Term ι} -theorem satisfying_of_mem (ht : (t.map Prod.fst).Nodup) {l : Literal ι} (hl : l ∈ t) : +private theorem satisfying_of_mem (ht : (t.map Prod.fst).Nodup) {l : Literal ι} (hl : l ∈ t) : t.satisfying l.1 = l.2 := by induction t with | nil => simp at hl @@ -103,7 +103,7 @@ theorem stageCode_eq_nil_iff {x : ι → Bool} {W : List ι} : t.stageCode x W = [] ↔ W = [] := by cases W <;> simp [stageCode] -theorem fst_lt_of_mem_stageCode {x : ι → Bool} {W : List ι} +private theorem fst_lt_of_mem_stageCode {x : ι → Bool} {W : List ι} (hW : ∀ v ∈ W, v ∈ t.map Prod.fst) {e : ℕ × Bool × Bool} (he : e ∈ t.stageCode x W) : e.1 < t.length := by induction W with @@ -119,23 +119,23 @@ namespace DNF variable {F : DNF ι} {ρ θ : PartialAssignment ι} {t : Term ι} -theorem queried_eq_freeVars (ht : F.firstTerm ρ = some t) : F.queried ρ = t.freeVars ρ := by +private theorem queried_eq_freeVars (ht : F.firstTerm ρ = some t) : F.queried ρ = t.freeVars ρ := by simp [queried, ht] -theorem exists_firstTerm_of_queried_ne_nil (h : F.queried ρ ≠ []) : +private theorem exists_firstTerm_of_queried_ne_nil (h : F.queried ρ ≠ []) : ∃ t, F.firstTerm ρ = some t := by cases ht : F.firstTerm ρ with | none => simp [queried, ht] at h | some t => exact ⟨t, rfl⟩ -theorem mem_of_firstTerm_eq_some (ht : F.firstTerm ρ = some t) : t ∈ F := +private theorem mem_of_firstTerm_eq_some (ht : F.firstTerm ρ = some t) : t ∈ F := List.mem_of_find?_eq_some ht -theorem not_falsifiedBy_of_firstTerm_eq_some (ht : F.firstTerm ρ = some t) : +private theorem not_falsifiedBy_of_firstTerm_eq_some (ht : F.firstTerm ρ = some t) : ¬ t.FalsifiedBy ρ := by simpa using List.find?_some ht -theorem nodup_queried (hF : ∀ t ∈ F, (t.map Prod.fst).Nodup) : (F.queried ρ).Nodup := by +private theorem nodup_queried (hF : ∀ t ∈ F, (t.map Prod.fst).Nodup) : (F.queried ρ).Nodup := by unfold queried cases ht : F.firstTerm ρ with | none => simp @@ -143,7 +143,7 @@ theorem nodup_queried (hF : ∀ t ∈ F, (t.map Prod.fst).Nodup) : (F.queried ρ simpa [Term.freeVars] using ((List.filter_sublist (l := t)).map Prod.fst).nodup (hF t (mem_of_firstTerm_eq_some ht)) -theorem mem_map_fst_of_mem_queried (ht : F.firstTerm ρ = some t) {v : ι} +private theorem mem_map_fst_of_mem_queried (ht : F.firstTerm ρ = some t) {v : ι} (hv : v ∈ F.queried ρ) : v ∈ t.map Prod.fst := by rw [queried_eq_freeVars ht] at hv obtain ⟨b, hb, -⟩ := Term.mem_freeVars.1 hv @@ -151,7 +151,7 @@ theorem mem_map_fst_of_mem_queried (ht : F.firstTerm ρ = some t) {v : ι} /-- Extending a restriction keeps its first term not falsified, as long as that term stays unfalsified. -/ -theorem firstTerm_eq_of_extends (ht : F.firstTerm ρ = some t) (h : θ.Extends ρ) +private theorem firstTerm_eq_of_extends (ht : F.firstTerm ρ = some t) (h : θ.Extends ρ) (hθ : ¬ t.FalsifiedBy θ) : F.firstTerm θ = some t := by rw [firstTerm, List.find?_eq_some_iff_append] at ht ⊢ @@ -163,7 +163,7 @@ variable [DecidableEq ι] /-- Fixing some queried variables to the values satisfying the first term keeps it first, in any extension leaving the other queried variables free. -/ -theorem firstTerm_assign_satisfying (hF : ∀ t ∈ F, (t.map Prod.fst).Nodup) +private theorem firstTerm_assign_satisfying (hF : ∀ t ∈ F, (t.map Prod.fst).Nodup) (ht : F.firstTerm ρ = some t) (h : θ.Extends ρ) {W : List ι} (hWq : ∀ v ∈ W, v ∈ F.queried ρ) (hW : ∀ v ∈ F.queried ρ, v ∉ W → θ v = none) : F.firstTerm (θ.assign W.toFinset t.satisfying) = some t := by @@ -207,7 +207,7 @@ def decode (θ : PartialAssignment ι) (c : List (ℕ × Bool × Bool)) : variable {F} /-- One step of the decoder: set the variable at position `j` of the current term to `b`. -/ -theorem decodeAux_cons {cur : Option (Term ι)} {θ : PartialAssignment ι} +private theorem decodeAux_cons {cur : Option (Term ι)} {θ : PartialAssignment ι} {t : Term ι} (ht : cur.getD ((F.firstTerm θ).getD []) = t) {j : ℕ} {v : ι} (hv : (t.map Prod.fst)[j]? = some v) (Q : Finset ι) (b e : Bool) (c : List (ℕ × Bool × Bool)) : @@ -217,7 +217,7 @@ theorem decodeAux_cons {cur : Option (Term ι)} {θ : PartialAssignment ι} simp only [decodeAux, hv] /-- Replaying a stage from its term. -/ -theorem decodeAux_stageCode {t : Term ι} {W : List ι} +private theorem decodeAux_stageCode {t : Term ι} {W : List ι} (hW : ∀ v ∈ W, v ∈ t.map Prod.fst) (hne : W ≠ []) (x : ι → Bool) (θ : PartialAssignment ι) (Q : Finset ι) (c : List (ℕ × Bool × Bool)) : F.decodeAux (some t) θ Q (t.stageCode x W ++ c) = @@ -255,7 +255,7 @@ theorem decodeAux_stageCode {t : Term ι} {W : List ι} tauto /-- At the start of a stage, the decoder reads the first term not falsified. -/ -theorem decodeAux_none {c : List (ℕ × Bool × Bool)} (hc : c ≠ []) (θ : PartialAssignment ι) +private theorem decodeAux_none {c : List (ℕ × Bool × Bool)} (hc : c ≠ []) (θ : PartialAssignment ι) (Q : Finset ι) : F.decodeAux none θ Q c = F.decodeAux ((F.firstTerm θ).getD []) θ Q c := by obtain ⟨⟨j, b, e⟩, c, rfl⟩ := List.exists_cons_of_ne_nil hc @@ -283,17 +283,17 @@ decreasing_by exact this variable {F} -theorem encode_of_queried_eq_nil (h : F.queried ρ = []) (s : ℕ) (x : ι → Bool) : +private theorem encode_of_queried_eq_nil (h : F.queried ρ = []) (s : ℕ) (x : ι → Bool) : F.encode s ρ x = (ρ, []) := by rw [encode, dite_eq_left h] -theorem encode_of_le (h : F.queried ρ ≠ []) {s : ℕ} (hs : s ≤ (F.queried ρ).length) +private theorem encode_of_le (h : F.queried ρ ≠ []) {s : ℕ} (hs : s ≤ (F.queried ρ).length) (x : ι → Bool) : F.encode s ρ x = (ρ.assign ((F.queried ρ).take s).toFinset ((F.firstTerm ρ).getD []).satisfying, ((F.firstTerm ρ).getD []).stageCode x ((F.queried ρ).take s)) := by rw [encode, dite_eq_right h, ite_eq_left hs] -theorem encode_of_lt (h : F.queried ρ ≠ []) {s : ℕ} (hs : (F.queried ρ).length < s) +private theorem encode_of_lt (h : F.queried ρ ≠ []) {s : ℕ} (hs : (F.queried ρ).length < s) (x : ι → Bool) : F.encode s ρ x = ((F.encode (s - (F.queried ρ).length) (ρ.assign (F.queried ρ).toFinset x) x).1.assign @@ -303,7 +303,7 @@ theorem encode_of_lt (h : F.queried ρ ≠ []) {s : ℕ} (hs : (F.queried ρ).le rw [encode, dite_eq_right h, ite_eq_right (by omega)] /-- The encoding extends the restriction it encodes. -/ -theorem encode_extends (s : ℕ) (ρ : PartialAssignment ι) (x : ι → Bool) : +private theorem encode_extends (s : ℕ) (ρ : PartialAssignment ι) (x : ι → Bool) : (F.encode s ρ x).1.Extends ρ := by intro i b hi have hiV : i ∉ (F.queried ρ).toFinset := fun hiV => by @@ -336,7 +336,7 @@ private theorem encode_assign_eq (s : ℕ) (x : ι → Bool) {i : ι} /-- Decoding the encoding of a restriction with a query path of length at least `s` gives the restriction back, freeing the accumulated variables `Q`. -/ -theorem decodeAux_encode (hF : ∀ t ∈ F, (t.map Prod.fst).Nodup) {ρ : PartialAssignment ι} +private theorem decodeAux_encode (hF : ∀ t ∈ F, (t.map Prod.fst).Nodup) {ρ : PartialAssignment ι} {s : ℕ} {x : ι → Bool} (hs : s ≤ F.pathLength ρ x) (Q : Finset ι) : F.decodeAux none (F.encode s ρ x).1 Q (F.encode s ρ x).2 = ρ.unassign Q := by by_cases h : F.queried ρ = [] @@ -383,7 +383,7 @@ theorem decode_encode (hF : ∀ t ∈ F, (t.map Prod.fst).Nodup) {s : ℕ} {x : rw [decode, decodeAux_encode hF hs, PartialAssignment.unassign_empty] /-- The encoding fixes `s` more variables. -/ -theorem card_free_encode (hF : ∀ t ∈ F, (t.map Prod.fst).Nodup) {ρ : PartialAssignment ι} +private theorem card_free_encode (hF : ∀ t ∈ F, (t.map Prod.fst).Nodup) {ρ : PartialAssignment ι} {s : ℕ} {x : ι → Bool} (hs : s ≤ F.pathLength ρ x) : #(F.encode s ρ x).1.free = #ρ.free - s := by by_cases h : F.queried ρ = [] @@ -412,7 +412,7 @@ termination_by #ρ.free decreasing_by exact card_free_assign_lt h x /-- The code of a query path of length at least `s` has length `s`. -/ -theorem length_encode {ρ : PartialAssignment ι} {s : ℕ} {x : ι → Bool} +private theorem length_encode {ρ : PartialAssignment ι} {s : ℕ} {x : ι → Bool} (hs : s ≤ F.pathLength ρ x) : (F.encode s ρ x).2.length = s := by by_cases h : F.queried ρ = [] · rw [pathLength_of_queried_eq_nil h] at hs @@ -432,7 +432,7 @@ termination_by #ρ.free decreasing_by exact card_free_assign_lt h x /-- The positions recorded in a code are positions in terms of at most `k` literals. -/ -theorem fst_lt_of_mem_encode {k : ℕ} (hF : ∀ t ∈ F, t.length ≤ k) (s : ℕ) +private theorem fst_lt_of_mem_encode {k : ℕ} (hF : ∀ t ∈ F, t.length ≤ k) (s : ℕ) (ρ : PartialAssignment ι) (x : ι → Bool) {e : ℕ × Bool × Bool} (he : e ∈ (F.encode s ρ x).2) : e.1 < k := by by_cases h : F.queried ρ = [] diff --git a/Complexity/Computability/MCSP/NP.lean b/Complexity/Computability/MCSP/NP.lean index 63de2378f..72246e9af 100644 --- a/Complexity/Computability/MCSP/NP.lean +++ b/Complexity/Computability/MCSP/NP.lean @@ -75,7 +75,7 @@ theorem encInstance_apply (x : Instance) : rfl /-- The table of an instance is no longer than its encoding. -/ -theorem two_pow_le_length_encInstance (x : Instance) : +private theorem two_pow_le_length_encInstance (x : Instance) : 2 ^ x.arity ≤ (encInstance x).length := by rw [encInstance_apply, length_encPair, encBits_apply, List.length_ofFn] omega @@ -122,7 +122,7 @@ theorem tableValue_ofFn (x : Instance) (y : BitString x.arity) : /-- The polynomial bounding the length of certificates. -/ noncomputable def certPolynomial : Polynomial ℕ := 40 * (Polynomial.X + 1) ^ 4 -theorem certLength_le (x : Instance) : +private theorem certLength_le (x : Instance) : certLength x.arity (budget x.arity x.threshold) ≤ certPolynomial.eval (encInstance x).length := by set L := (encInstance x).length diff --git a/Complexity/Computability/PCP/Approximation/Hastad.lean b/Complexity/Computability/PCP/Approximation/Hastad.lean index cfe2d914d..626852bde 100644 --- a/Complexity/Computability/PCP/Approximation/Hastad.lean +++ b/Complexity/Computability/PCP/Approximation/Hastad.lean @@ -84,7 +84,7 @@ section LabelCoverSoundness `W : I → α → ℝ`, and vertex-wise sub-probability distributions `p : ℕ → α → ℝ` (`0 ≤ p u a` and `∑ a, p u a ≤ 1`), choosing the best label at each vertex produces a deterministic assignment `f : ℕ → α` whose payoff is at least the expected payoff under `p`. -/ -theorem exists_choice_sum_le {I α : Type*} [Fintype I] [Fintype α] [Nonempty α] +private theorem exists_choice_sum_le {I α : Type*} [Fintype I] [Fintype α] [Nonempty α] (v : I → ℕ) (W : I → α → ℝ) (hW : ∀ i a, 0 ≤ W i a) (p : ℕ → α → ℝ) (hp0 : ∀ u a, 0 ≤ p u a) (hp1 : ∀ u, ∑ a : α, p u a ≤ 1) : ∃ f : ℕ → α, (∑ i : I, ∑ a : α, p (v i) a * W i a) ≤ ∑ i : I, W i (f (v i)) := by @@ -128,7 +128,7 @@ theorem exists_choice_sum_le {I α : Type*} [Fintype I] [Fintype α] [Nonempty /-- Any deterministic labelling `(ℓ, r)` of a Label Cover instance `g` satisfies at most `g.edges.length * (1 - (g.toGraph projectionEval).unsatVal)` edges. -/ -theorem sum_satisfies_le_unsatVal {β γ : Type} [DecidableEq γ] +private theorem sum_satisfies_le_unsatVal {β γ : Type} [DecidableEq γ] (g : Graph (β → γ)) (ℓ : ℕ → β) (r : ℕ → γ) : (∑ i : Fin g.edges.length, if (g.edges.get i).constraint (ℓ (g.edges.get i).src) = r (g.edges.get i).dst then (1 : ℝ) @@ -198,7 +198,7 @@ theorem exists_labelling_of_spectralWeight (g : Graph (β → γ)) (k : ℕ) /-- Total spectral weight agreement across the edges of a Label Cover instance `g` is at most `g.edges.length * (1 - (g.toGraph projectionEval).unsatVal)`. -/ -theorem sum_spectralWeight_le_unsatVal (g : Graph (β → γ)) (k : ℕ) +private theorem sum_spectralWeight_le_unsatVal (g : Graph (β → γ)) (k : ℕ) (B : ℕ → (γ → Bool) → Bool) (A : ℕ → (β → Bool) → Bool) : (∑ i : Fin g.edges.length, ∑ x : β, spectralWeight k (A (g.edges.get i).src) x * @@ -224,7 +224,7 @@ noncomputable def hastadGraphLinearProb (g : Graph (β → γ)) (δ : ℝ) omit [Nonempty β] [Nonempty γ] in /-- For a Label Cover instance with at least one edge, `hastadGraphLinearProb g δ B A = 1 / 2 + 1 / 2 * hastadGraphLinearCorr g δ B A`. -/ -theorem hastadGraphLinearProb_eq_add_hastadGraphLinearCorr {g : Graph (β → γ)} +private theorem hastadGraphLinearProb_eq_add_hastadGraphLinearCorr {g : Graph (β → γ)} (hg : g.edges ≠ []) (δ : ℝ) (B : ℕ → (γ → Bool) → Bool) (A : ℕ → (β → Bool) → Bool) : hastadGraphLinearProb g δ B A = 1 / 2 + 1 / 2 * hastadGraphLinearCorr g δ B A := by have hne : (univ : Finset (Fin g.edges.length)).Nonempty := @@ -307,7 +307,7 @@ theorem hastadGraphLinearCorr_sq_le (g : Graph (β → γ)) {δ : ℝ} (hδ0 : 0 `1 - (g.toGraph projectionEval).unsatVal ≤ η` and `(1 - 2 * δ) ^ (2 * k) + k ^ 2 * η ≤ (8 * ε) ^ 2` (`0 ≤ ε`), every assignment of folded right tables `B` and left tables `A` has average linear correlation at most `8 * ε`. -/ -theorem hastadGraphLinearCorr_le_of_unsatVal (g : Graph (β → γ)) {δ : ℝ} (hδ0 : 0 ≤ δ) +private theorem hastadGraphLinearCorr_le_of_unsatVal (g : Graph (β → γ)) {δ : ℝ} (hδ0 : 0 ≤ δ) (hδ1 : δ ≤ 1 / 2) (k : ℕ) {η ε : ℝ} (hε : 0 ≤ ε) (hη : 1 - (g.toGraph projectionEval).unsatVal ≤ η) (hparam : (1 - 2 * δ) ^ (2 * k) + (k : ℝ) ^ 2 * η ≤ (8 * ε) ^ 2) @@ -323,7 +323,7 @@ theorem hastadGraphLinearCorr_le_of_unsatVal (g : Graph (β → γ)) {δ : ℝ} /-- For every `ε > 0` and `0 < δ < 1 / 2`, there exist a degree cutoff `k : ℕ` and a Label Cover soundness threshold `η > 0` such that `(1 - 2 * δ) ^ (2 * k) + k ^ 2 * η ≤ (8 * ε) ^ 2`. -/ -theorem exists_hastad_params {ε δ : ℝ} (hε : 0 < ε) (hδ0 : 0 < δ) (hδ1 : δ < 1 / 2) : +private theorem exists_hastad_params {ε δ : ℝ} (hε : 0 < ε) (hδ0 : 0 < δ) (hδ1 : δ < 1 / 2) : ∃ (k : ℕ) (η : ℝ), 0 < η ∧ (1 - 2 * δ) ^ (2 * k) + (k : ℝ) ^ 2 * η ≤ (8 * ε) ^ 2 := by have hρ0 : 0 ≤ 1 - 2 * δ := by linarith have hρ1 : 1 - 2 * δ < 1 := by linarith diff --git a/Complexity/Computability/PCP/Approximation/IndependentSet.lean b/Complexity/Computability/PCP/Approximation/IndependentSet.lean index 6e1b50755..ad27a651d 100644 --- a/Complexity/Computability/PCP/Approximation/IndependentSet.lean +++ b/Complexity/Computability/PCP/Approximation/IndependentSet.lean @@ -116,7 +116,7 @@ theorem card_toFinset_vertices_toIndependentSet {φ : CNF ℕ} (h3 : ∀ c ∈ (Nat.pair_eq_pair.1 h).2, Finset.card_product, Finset.card_range, Finset.card_range, Nat.mul_comm] -theorem toIndependentSet_snd (φ : CNF ℕ) : (toIndependentSet φ).2 = φ.length := +private theorem toIndependentSet_snd (φ : CNF ℕ) : (toIndependentSet φ).2 = φ.length := rfl /-- **The independence number of Karp's graph is at most the largest number of clauses an diff --git a/Complexity/Computability/PCP/Approximation/MaxExactThreeSAT.lean b/Complexity/Computability/PCP/Approximation/MaxExactThreeSAT.lean index 87086339b..95b5f126b 100644 --- a/Complexity/Computability/PCP/Approximation/MaxExactThreeSAT.lean +++ b/Complexity/Computability/PCP/Approximation/MaxExactThreeSAT.lean @@ -125,13 +125,14 @@ def reduce (φ : CNF ℕ) : CNF ℕ := if φ.any List.isEmpty then contradiction else toExactThreeSAT φ /-- Padding the clauses does not change the number of clauses an assignment falsifies. -/ -theorem countUnsat_toExactThreeSAT (σ : ℕ → Bool) (φ : CNF ℕ) : +private theorem countUnsat_toExactThreeSAT (σ : ℕ → Bool) (φ : CNF ℕ) : (toExactThreeSAT φ).countUnsat σ = φ.countUnsat σ := by simp only [toExactThreeSAT, CNF.countUnsat, List.countP_map, Function.comp_def, ExactThreeSAT.eval_padClause] /-- Padding the clauses does not change the value of a formula. -/ -theorem unsatVal_toExactThreeSAT (φ : CNF ℕ) : (toExactThreeSAT φ).unsatVal = φ.unsatVal := by +private theorem unsatVal_toExactThreeSAT (φ : CNF ℕ) : + (toExactThreeSAT φ).unsatVal = φ.unsatVal := by unfold CNF.unsatVal simp only [countUnsat_toExactThreeSAT] rw [toExactThreeSAT, List.length_map] @@ -251,13 +252,13 @@ theorem Clause.isExactThreeDistinct_iff {c : Clause V} : /-- The falsification indicator of a literal `(v, b)` under `σ` is `(1 - signVal b * signVal (σ v)) / 2`. -/ -theorem Literal.if_eval_eq_zero_one (l : Literal V) (σ : V → Bool) : +private theorem Literal.if_eval_eq_zero_one (l : Literal V) (σ : V → Bool) : (if l.eval σ then (0 : ℝ) else 1) = (1 - signVal l.2 * signVal (σ l.1)) / 2 := by rcases l with ⟨v, b⟩ cases b <;> cases h : σ v <;> simp [Literal.eval, signVal, h] /-- A clause `l :: c` is falsified iff both `l` and `c` are falsified. -/ -theorem Clause.if_eval_cons_eq_mul (l : Literal V) (c : Clause V) (σ : V → Bool) : +private theorem Clause.if_eval_cons_eq_mul (l : Literal V) (c : Clause V) (σ : V → Bool) : (if Clause.eval σ (l :: c) then (0 : ℝ) else 1) = (if l.eval σ then (0 : ℝ) else 1) * (if c.eval σ then (0 : ℝ) else 1) := by rw [Clause.eval_cons] @@ -348,7 +349,8 @@ theorem Clause.IsExactThreeDistinct.card_eval_eq_true {c : Clause (Fin 3)} /-- The expected number of falsified clauses in an exact 3-CNF formula with distinct variables per clause under a uniform random assignment is `φ.length / 8`. -/ -theorem CNF.IsExactThreeDistinct.expect_countUnsat {φ : CNF ι} (hφ : φ.IsExactThreeDistinct) : +private theorem CNF.IsExactThreeDistinct.expect_countUnsat {φ : CNF ι} + (hφ : φ.IsExactThreeDistinct) : (𝔼 σ : ι → Bool, (φ.countUnsat σ : ℝ)) = (φ.length : ℝ) / 8 := by induction φ with | nil => simp [CNF.countUnsat] @@ -368,7 +370,7 @@ end FintypeCube /-- Relabelling a clause along a map that is injective on its variables preserves `Clause.IsExactThreeDistinct`. -/ -theorem Clause.IsExactThreeDistinct.relabel_of_injOn {f : V → ι} {c : Clause V} +private theorem Clause.IsExactThreeDistinct.relabel_of_injOn {f : V → ι} {c : Clause V} (hf : ∀ x ∈ c.map Prod.fst, ∀ y ∈ c.map Prod.fst, f x = f y → x = y) (hc : c.IsExactThreeDistinct) : (c.relabel f).IsExactThreeDistinct := by refine ⟨by rw [Clause.length_relabel, hc.1], ?_⟩ diff --git a/Complexity/Computability/PCP/Approximation/MaxThreeSAT.lean b/Complexity/Computability/PCP/Approximation/MaxThreeSAT.lean index fd6f3db02..f92dc4fa5 100644 --- a/Complexity/Computability/PCP/Approximation/MaxThreeSAT.lean +++ b/Complexity/Computability/PCP/Approximation/MaxThreeSAT.lean @@ -78,7 +78,7 @@ namespace CNF variable (φ : CNF V) /-- The proportions of falsified clauses are bounded below, by zero. -/ -theorem bddBelow_range_countUnsat_div : +private theorem bddBelow_range_countUnsat_div : BddBelow (Set.range fun σ : V → Bool => (φ.countUnsat σ : ℝ) / φ.length) := ⟨0, Set.forall_mem_range.2 fun _ => by positivity⟩ @@ -135,7 +135,8 @@ end CNF /-! ### Splitting clauses -/ /-- The chain for a clause `carry :: rest` has `rest.length - 1` clauses, and at least one. -/ -theorem Clause.length_splitAux (fresh : ℕ → W) (j : ℕ) (carry : Literal W) (rest : Clause W) : +private theorem Clause.length_splitAux (fresh : ℕ → W) (j : ℕ) (carry : Literal W) + (rest : Clause W) : (Clause.splitAux fresh j carry rest).length = max 1 (rest.length - 1) := by induction j, carry, rest using Clause.splitAux.induct fresh with | case1 j carry b c d rest ih => @@ -150,7 +151,7 @@ theorem Clause.length_splitAux (fresh : ℕ → W) (j : ℕ) (carry : Literal W) · exact hrest /-- Splitting a clause of width `w` gives `w - 2` clauses, and at least one. -/ -theorem Clause.length_split3 (fresh : ℕ → W) (j : ℕ) (c : Clause W) : +private theorem Clause.length_split3 (fresh : ℕ → W) (j : ℕ) (c : Clause W) : (Clause.split3 fresh j c).length = max 1 (c.length - 2) := by cases c with | nil => rfl @@ -251,7 +252,8 @@ theorem eval_excludeClause_eq_true_iff (τ : ℕ → Bool) (u v : ℕ) (p : α exacts [⟨_, Or.inl ⟨i, rfl⟩, hi⟩, ⟨_, Or.inr ⟨i, rfl⟩, hi⟩] /-- Every clause of `toCNF` has width `2 k`. -/ -theorem length_of_mem_toCNF {g : Graph (α → α → Bool)} {c : Clause ℕ} (hc : c ∈ toCNF e pairs g) : +private theorem length_of_mem_toCNF {g : Graph (α → α → Bool)} {c : Clause ℕ} + (hc : c ∈ toCNF e pairs g) : c.length = 2 * k := by obtain ⟨d, -, hc⟩ := List.mem_flatMap.1 hc obtain ⟨p, -, rfl⟩ := List.mem_map.1 hc @@ -259,7 +261,7 @@ theorem length_of_mem_toCNF {g : Graph (α → α → Bool)} {c : Clause ℕ} (h omega /-- Each edge produces at most `pairs.length` clauses. -/ -theorem length_toCNF_le (g : Graph (α → α → Bool)) : +private theorem length_toCNF_le (g : Graph (α → α → Bool)) : (toCNF e pairs g).length ≤ g.edges.length * pairs.length := by rw [toCNF, List.length_flatMap] refine (List.sum_le_length_nsmul _ pairs.length fun n hn => ?_).trans (by simp) @@ -300,7 +302,7 @@ private theorem card_filter_get_eq_countP {β : Type*} (p : β → Bool) (l : Li congr /-- The violated edges of a constraint graph, counted along its edge list. -/ -theorem card_unsatEdges_toGraph (g : Graph (α → α → Bool)) (σ : ℕ → α) : +private theorem card_unsatEdges_toGraph (g : Graph (α → α → Bool)) (σ : ℕ → α) : #((g.toGraph id).unsatEdges σ) = g.edges.countP fun d => !d.constraint (σ d.src) (σ d.dst) := by rw [← card_filter_get_eq_countP] congr 1 @@ -310,7 +312,7 @@ theorem card_unsatEdges_toGraph (g : Graph (α → α → Bool)) (σ : ℕ → /-- **Every violated edge leaves a falsified clause**: an assignment falsifies at least as many clauses of the formula as the labelling it writes violates edges, when `pairs` lists all pairs of labels. -/ -theorem card_unsatEdges_le_countUnsat (hpairs : ∀ p, p ∈ pairs) (g : Graph (α → α → Bool)) +private theorem card_unsatEdges_le_countUnsat (hpairs : ∀ p, p ∈ pairs) (g : Graph (α → α → Bool)) (τ : ℕ → Bool) : #((g.toGraph id).unsatEdges (readLabel e τ)) ≤ (toCNF e pairs g).countUnsat τ := by rw [card_unsatEdges_toGraph, CNF.countUnsat, toCNF, List.countP_flatMap] @@ -322,7 +324,7 @@ theorem card_unsatEdges_le_countUnsat (hpairs : ∀ p, p ∈ pairs) (g : Graph ( /-- Splitting the clauses of `toCNF`, all of width `2 k`, gives `2 k - 2` clauses for each, and at least one. -/ -theorem length_toThreeSAT_toCNF (g : Graph (α → α → Bool)) : +private theorem length_toThreeSAT_toCNF (g : Graph (α → α → Bool)) : (toThreeSAT (toCNF e pairs g)).length = (toCNF e pairs g).length * max 1 (2 * k - 2) := by rw [toThreeSAT, CNF.relabel, List.length_map, CNF.length_to3CNF, List.map_congr_left fun c hc => by rw [length_of_mem_toCNF e pairs hc], List.map_const', diff --git a/Complexity/Computability/PCP/AssignmentTester.lean b/Complexity/Computability/PCP/AssignmentTester.lean index 6c9bb5c6c..9dc567b1b 100644 --- a/Complexity/Computability/PCP/AssignmentTester.lean +++ b/Complexity/Computability/PCP/AssignmentTester.lean @@ -148,7 +148,7 @@ def equationRhs : (Fin 2 × α) × (Fin 2 × α) ⊕ Fin 2 → Bool := open Classical in /-- The equation of a pair of variables, read on the tensor square of `x`. -/ -theorem hadamardCode_tensor_equationCoeff_inl (C : α → α → Prop) (x : Fin 2 × α → Bool) +private theorem hadamardCode_tensor_equationCoeff_inl (C : α → α → Prop) (x : Fin 2 × α → Bool) (p p' : Fin 2 × α) : hadamardCode (tensor x x) (equationCoeff C (.inl (p, p'))) = if Compatible C p p' then false else (x p && x p') := by @@ -159,7 +159,7 @@ theorem hadamardCode_tensor_equationCoeff_inl (C : α → α → Prop) (x : Fin /-- The equation of an end, read on the tensor square of `x`: the sum of the variables of the end. -/ -theorem hadamardCode_tensor_equationCoeff_inr (C : α → α → Prop) (x : Fin 2 × α → Bool) +private theorem hadamardCode_tensor_equationCoeff_inr (C : α → α → Prop) (x : Fin 2 × α → Bool) (b : Fin 2) : hadamardCode (tensor x x) (equationCoeff C (.inr b)) = ∑ a, x (b, a) := by rw [equationCoeff, Sum.elim_inr, hadamardCode_apply, dotProduct_sum] @@ -234,7 +234,7 @@ def endEmbed (b : Fin 2) (r : α → Bool) : Fin 2 × α → Bool := omit [DecidableEq α] in /-- The Hadamard encoding of the variables `x`, read at `endEmbed b r`, is that of the variables of the end `b`, read at `r`. -/ -theorem hadamardCode_endEmbed (x : Fin 2 × α → Bool) (b : Fin 2) (r : α → Bool) : +private theorem hadamardCode_endEmbed (x : Fin 2 × α → Bool) (b : Fin 2) (r : α → Bool) : hadamardCode x (endEmbed b r) = hadamardCode (fun a ↦ x (b, a)) r := by rw [hadamardCode_apply, hadamardCode_apply, dotProduct, dotProduct, Fintype.sum_prod_type, sum_eq_single b] @@ -246,7 +246,7 @@ theorem hadamardCode_endEmbed (x : Fin 2 × α → Bool) (b : Fin 2) (r : α → /-- The Hadamard encoding of the one-hot encoding of the labels `σ`, read at `endEmbed b r`, is the long code of the label of the end `b`, read at `r`. -/ -theorem hadamardCode_oneHot_endEmbed (σ : Fin 2 → α) (b : Fin 2) (r : α → Bool) : +private theorem hadamardCode_oneHot_endEmbed (σ : Fin 2 → α) (b : Fin 2) (r : α → Bool) : hadamardCode (oneHot σ) (endEmbed b r) = longCode (σ b) r := by rw [hadamardCode_endEmbed, longCode_eq_hadamardCode] congr 1 @@ -267,7 +267,7 @@ def blrTest : LocalTest (ι → Bool) ((ι → Bool) × (ι → Bool)) (Fin 3) B Accepts _ a := (a 0 ^^ a 1) = a 2 /-- The linearity test accepts with the probability `blrAcceptance`. -/ -theorem acceptProb_blrTest [Fintype ι] [DecidableEq ι] (f : (ι → Bool) → Bool) : +private theorem acceptProb_blrTest [Fintype ι] [DecidableEq ι] (f : (ι → Bool) → Bool) : (blrTest ι).acceptProb f = blrAcceptance f := by simp only [LocalTest.acceptProb, Fintype.expect_prod_type, LocalTest.Passes, blrTest, blrAcceptance, Matrix.cons_val] @@ -286,7 +286,7 @@ def tensorTest : LocalTest ((ι → Bool) ⊕ (ι × ι → Bool)) Accepts _ a := (a 0 ^^ a 1) = ((a 2 ^^ a 3) && (a 4 ^^ a 5)) /-- The tensor test accepts with the probability `tensorTestAcceptance`. -/ -theorem acceptProb_tensorTest [Fintype ι] [DecidableEq ι] (f : (ι → Bool) → Bool) +private theorem acceptProb_tensorTest [Fintype ι] [DecidableEq ι] (f : (ι → Bool) → Bool) (g : (ι × ι → Bool) → Bool) : (tensorTest ι).acceptProb (Sum.elim f g) = tensorTestAcceptance f g := by simp only [LocalTest.acceptProb, Fintype.expect_prod_type, LocalTest.Passes, tensorTest, @@ -305,7 +305,7 @@ def equationTest [Fintype κ] (A : κ → ι → Bool) (b : κ → Bool) : Accepts ω a := (a 0 ^^ a 1) = hadamardCode ω.1 b /-- The equation test accepts with the probability `equationTestAcceptance`. -/ -theorem acceptProb_equationTest [Fintype ι] [DecidableEq ι] [Fintype κ] [DecidableEq κ] +private theorem acceptProb_equationTest [Fintype ι] [DecidableEq ι] [Fintype κ] [DecidableEq κ] (g : (ι → Bool) → Bool) (A : κ → ι → Bool) (b : κ → Bool) : (equationTest A b).acceptProb g = equationTestAcceptance g A b := by simp only [LocalTest.acceptProb, Fintype.expect_prod_type, LocalTest.Passes, equationTest, @@ -324,7 +324,8 @@ def inputTest : LocalTest ((Fin 2 × (α → Bool)) ⊕ (Fin 2 × α → Bool)) /-- The input test accepts when the bit of the table of a random end at a random point is the self-corrected read of the linear table at the corresponding vector. -/ -theorem acceptProb_inputTest (T : Fin 2 → (α → Bool) → Bool) (f : (Fin 2 × α → Bool) → Bool) : +private theorem acceptProb_inputTest (T : Fin 2 → (α → Bool) → Bool) + (f : (Fin 2 × α → Bool) → Bool) : (inputTest α).acceptProb (Sum.elim (fun p ↦ T p.1 p.2) f) = 𝔼 b, 𝔼 r, 𝔼 y, if T b r = selfCorrect f (endEmbed b r) y then 1 else 0 := by simp only [LocalTest.acceptProb, Fintype.expect_prod_type, LocalTest.Passes, inputTest, @@ -343,7 +344,8 @@ private theorem one_sub_boole_le {A B F : Prop} [Decidable A] [Decidable B] [Dec Hadamard encoding of `x`, then on average over the ends `b`, the table `T b` is within relative distance `1 - p + 2ε` of `r ↦ hadamardCode x (endEmbed b r)`, where `p` is the acceptance probability of the input test. -/ -theorem expect_hammingDist_div_le_one_sub_acceptProb_inputTest {T : Fin 2 → (α → Bool) → Bool} +private theorem expect_hammingDist_div_le_one_sub_acceptProb_inputTest + {T : Fin 2 → (α → Bool) → Bool} {f : (Fin 2 × α → Bool) → Bool} {x : Fin 2 × α → Bool} {ε : ℝ} (hf : (hammingDist f (hadamardCode x) : ℝ) / 2 ^ Fintype.card (Fin 2 × α) ≤ ε) : 𝔼 b, (hammingDist (T b) (fun r ↦ hadamardCode x (endEmbed b r)) : ℝ) / 2 ^ Fintype.card α ≤ @@ -452,11 +454,11 @@ def inputTable (π : Pos α → Bool) (b : Fin 2) : (α → Bool) → Bool := fun r ↦ π (.inl (b, r)) /-- The linear table carried by the proof `π`. -/ -def linTable (π : Pos α → Bool) : (Fin 2 × α → Bool) → Bool := +private def linTable (π : Pos α → Bool) : (Fin 2 × α → Bool) → Bool := fun y ↦ π (.inr (.inl y)) /-- The quadratic table carried by the proof `π`. -/ -def quadTable (π : Pos α → Bool) : ((Fin 2 × α) × (Fin 2 × α) → Bool) → Bool := +private def quadTable (π : Pos α → Bool) : ((Fin 2 × α) × (Fin 2 × α) → Bool) → Bool := fun z ↦ π (.inr (.inr z)) end HadamardTester @@ -482,7 +484,7 @@ namespace HadamardTester variable {C : α → α → Prop} /-- The tester accepts at most as often as each of its five checks. -/ -theorem acceptProb_le (π : Pos α → Bool) : +private theorem acceptProb_le (π : Pos α → Bool) : (hadamardTester C).acceptProb π ≤ blrAcceptance (linTable π) ∧ (hadamardTester C).acceptProb π ≤ blrAcceptance (quadTable π) ∧ (hadamardTester C).acceptProb π ≤ tensorTestAcceptance (linTable π) (quadTable π) ∧ @@ -522,7 +524,7 @@ noncomputable def inputDist (π : Pos α → Bool) (σ : Fin 2 → α) : ℝ := /-- The distance of the tables of `π` from the long codes of `σ` is the average of the distances of the two tables. -/ -theorem inputDist_eq (π : Pos α → Bool) (σ : Fin 2 → α) : +private theorem inputDist_eq (π : Pos α → Bool) (σ : Fin 2 → α) : inputDist π σ = ((hammingDist (inputTable π 0) (longCode (σ 0)) : ℝ) / 2 ^ Fintype.card α + (hammingDist (inputTable π 1) (longCode (σ 1)) : ℝ) / 2 ^ Fintype.card α) / 2 := by diff --git a/Complexity/Computability/PCP/AssignmentTester/Selection.lean b/Complexity/Computability/PCP/AssignmentTester/Selection.lean index 53d175ed7..a1faa5000 100644 --- a/Complexity/Computability/PCP/AssignmentTester/Selection.lean +++ b/Complexity/Computability/PCP/AssignmentTester/Selection.lean @@ -60,7 +60,7 @@ def checks (coeff : ((Fin 2 × α) × (Fin 2 × α) ⊕ Fin 2) → /-- On the shared product coins, the original tester passes precisely when all padded checks pass. This coupling is used only in the proof; the selected tester reads just one check. -/ -theorem passes_iff_forall_checks (C : α → α → Prop) (π : Pos α → Bool) (ω : Rand α) : +private theorem passes_iff_forall_checks (C : α → α → Prop) (π : Pos α → Bool) (ω : Rand α) : (hadamardTester C).Passes π ω ↔ ∀ i, (checks (equationCoeff C) i).Passes π ω := by simp [checks, hadamardTester, Fin.forall_fin_succ] diff --git a/Complexity/Computability/PCP/Composition.lean b/Complexity/Computability/PCP/Composition.lean index d43e92418..a6c5da419 100644 --- a/Complexity/Computability/PCP/Composition.lean +++ b/Complexity/Computability/PCP/Composition.lean @@ -124,7 +124,7 @@ noncomputable def decodeLabel (T : (α → Bool) → Bool) : α := /-- **Unique decoding**: a table within relative distance `1/4` of the long code of a label decodes to that label. -/ -theorem decodeLabel_eq {T : (α → Bool) → Bool} {a : α} +private theorem decodeLabel_eq {T : (α → Bool) → Bool} {a : α} (h : (hammingDist T (longCode a) : ℝ) / 2 ^ Fintype.card α < 1 / 4) : decodeLabel T = a := by have hex : ∃ a : α, (hammingDist T (longCode a) : ℝ) / 2 ^ Fintype.card α < 1 / 4 := ⟨a, h⟩ diff --git a/Complexity/Computability/PCP/DegreeReduction.lean b/Complexity/Computability/PCP/DegreeReduction.lean index e2f5bc32d..42f1bc88d 100644 --- a/Complexity/Computability/PCP/DegreeReduction.lean +++ b/Complexity/Computability/PCP/DegreeReduction.lean @@ -72,7 +72,8 @@ open Finset /-- **Plurality**: some value of a function on a finite type is taken at least as often as any other. -/ -theorem Fintype.exists_forall_card_filter_le_card_filter {ι α : Type*} [Fintype ι] [Nonempty α] +private theorem Fintype.exists_forall_card_filter_le_card_filter {ι α : Type*} [Fintype ι] + [Nonempty α] [DecidableEq α] (f : ι → α) : ∃ a, ∀ b, #{i | f i = b} ≤ #{i | f i = a} := by rcases isEmpty_or_nonempty ι with h | ⟨⟨i₀⟩⟩ · exact ⟨Classical.arbitrary α, fun b ↦ by simp [univ_eq_empty]⟩ @@ -132,7 +133,7 @@ variable {G} (H : ∀ v, RotationMap (G.Cloud v) D) /-- The neighbors of a half-edge in the cloud graph are its neighbors in the multigraph on its cloud. -/ -theorem neighbor_cloudGraph {v : V} (x : G.Cloud v) (i : D) : +private theorem neighbor_cloudGraph {v : V} (x : G.Cloud v) (i : D) : (G.cloudGraph H).neighbor x.1 i = ((H v).neighbor x i).1 := by obtain ⟨x, rfl⟩ := x rfl @@ -177,26 +178,26 @@ theorem graph_degreeReduce : (G.degreeReduce H).graph = halfEdgeGraph.union (G.c /-- The edge-links at both halves of an edge carry its constraint, read from its first end to its second one. -/ -theorem satisfies_degreeReduce_inl {A : E × Bool → α} {p : E × Bool} {i : Unit} : +private theorem satisfies_degreeReduce_inl {A : E × Bool → α} {p : E × Bool} {i : Unit} : (G.degreeReduce H).toConstraintGraph.Satisfies A (p, .inl i) ↔ G.rel p.1 (A (p.1, false)) (A (p.1, true)) := by obtain ⟨e, _ | _⟩ := p <;> rfl /-- The cloud-links carry equality constraints. -/ -theorem satisfies_degreeReduce_inr {A : E × Bool → α} {p : E × Bool} {i : D} : +private theorem satisfies_degreeReduce_inr {A : E × Bool → α} {p : E × Bool} {i : D} : (G.degreeReduce H).toConstraintGraph.Satisfies A (p, .inr i) ↔ A p = A ((G.cloudGraph H).neighbor p i) := by obtain ⟨e, _ | _⟩ := p <;> rfl /-- The labelling of the half-edges by the labels of their vertices satisfies the edge-links of an edge exactly when the labelling of the vertices satisfies the edge. -/ -theorem satisfies_degreeReduce_comp_endpoint_inl {σ : V → α} {p : E × Bool} {i : Unit} : +private theorem satisfies_degreeReduce_comp_endpoint_inl {σ : V → α} {p : E × Bool} {i : Unit} : (G.degreeReduce H).toConstraintGraph.Satisfies (σ ∘ G.endpoint) (p, .inl i) ↔ G.Satisfies σ p.1 := satisfies_degreeReduce_inl H /-- The labelling of the half-edges by the labels of their vertices satisfies the cloud-links. -/ -theorem satisfies_degreeReduce_comp_endpoint_inr (σ : V → α) (p : E × Bool) (i : D) : +private theorem satisfies_degreeReduce_comp_endpoint_inr (σ : V → α) (p : E × Bool) (i : D) : (G.degreeReduce H).toConstraintGraph.Satisfies (σ ∘ G.endpoint) (p, .inr i) := by rw [satisfies_degreeReduce_inr, Function.comp_apply, Function.comp_apply, endpoint_neighbor_cloudGraph] @@ -216,14 +217,14 @@ section Count variable [Fintype E] [Fintype D] /-- The degree-reduced constraint graph has `2 (1 + |D|) |E|` darts. -/ -theorem card_darts_degreeReduce : +private theorem card_darts_degreeReduce : Fintype.card ((E × Bool) × (Unit ⊕ D)) = 2 * (1 + Fintype.card D) * Fintype.card E := by simp only [Fintype.card_prod, Fintype.card_bool, Fintype.card_sum, Fintype.card_unit] ring /-- The labelling of the half-edges by the labels of their vertices violates only the edge-links of the edges violated by the labelling of the vertices. -/ -theorem card_unsatEdges_degreeReduce_comp_endpoint_le (σ : V → α) : +private theorem card_unsatEdges_degreeReduce_comp_endpoint_le (σ : V → α) : #((G.degreeReduce H).toConstraintGraph.unsatEdges (σ ∘ G.endpoint)) ≤ 2 * #(G.unsatEdges σ) := by classical @@ -267,7 +268,8 @@ theorem one_add_card_mul_unsatVal_degreeReduce_le [Nonempty α] : /-- **The edge charge**: an edge violated by a labelling `σ` of the vertices either has a half-edge whose label under `A` differs from that of its vertex, or its edge-links are violated by `A`. -/ -theorem card_unsatEdges_le_card_filter_isLeft_add [DecidableEq α] (A : E × Bool → α) (σ : V → α) : +private theorem card_unsatEdges_le_card_filter_isLeft_add [DecidableEq α] (A : E × Bool → α) + (σ : V → α) : #(G.unsatEdges σ) ≤ #{q ∈ (G.degreeReduce H).toConstraintGraph.unsatEdges A | q.2.isLeft} + #{p | A p ≠ σ (G.endpoint p)} := by classical @@ -292,7 +294,8 @@ section Soundness variable [Fintype E] [DecidableEq V] [Fintype D] /-- **Plurality**: some label is taken by at least as many half-edges of a cloud as any other. -/ -theorem exists_forall_card_filter_le_card_filter [Nonempty α] [DecidableEq α] (A : E × Bool → α) +private theorem exists_forall_card_filter_le_card_filter [Nonempty α] [DecidableEq α] + (A : E × Bool → α) (v : V) : ∃ a : α, ∀ b, #{x : G.Cloud v | A x.1 = b} ≤ #{x : G.Cloud v | A x.1 = a} := Fintype.exists_forall_card_filter_le_card_filter fun x : G.Cloud v ↦ A x.1 @@ -303,7 +306,7 @@ variable {μ : ℝ} `σ v` is a most frequent label of the cloud of every vertex `v`, then the cloud-links violated by `A` number at least `(1 - μ) |D|` times the half-edges whose label differs from that of their vertex. -/ -theorem mul_card_filter_ne_le_card_filter_isRight [DecidableEq α] +private theorem mul_card_filter_ne_le_card_filter_isRight [DecidableEq α] (hH : ∀ v, (H v).spectralExpansion ≤ μ) (A : E × Bool → α) (σ : V → α) (hσ : ∀ v b, #{x : G.Cloud v | A x.1 = b} ≤ #{x : G.Cloud v | A x.1 = σ v}) : (1 - μ) * Fintype.card D * #{p | A p ≠ σ (G.endpoint p)} ≤ @@ -368,7 +371,7 @@ theorem mul_card_filter_ne_le_card_filter_isRight [DecidableEq α] clouds have spectral expansion at most `μ`, every labelling of the half-edges violates a proportion of the darts at least `min 1 ((1 - μ) |D|) / (2 (1 + |D|))` times the value of `G`, whatever the alphabet. -/ -theorem le_unsatFrac_degreeReduce [Nonempty α] (hH : ∀ v, (H v).spectralExpansion ≤ μ) +private theorem le_unsatFrac_degreeReduce [Nonempty α] (hH : ∀ v, (H v).spectralExpansion ≤ μ) (A : E × Bool → α) : min 1 ((1 - μ) * Fintype.card D) / (2 * (1 + Fintype.card D)) * G.unsatVal ≤ (G.degreeReduce H).toConstraintGraph.unsatFrac A := by diff --git a/Complexity/Computability/PCP/Encoded/Constraints.lean b/Complexity/Computability/PCP/Encoded/Constraints.lean index c04e26147..00d41449f 100644 --- a/Complexity/Computability/PCP/Encoded/Constraints.lean +++ b/Complexity/Computability/PCP/Encoded/Constraints.lean @@ -154,7 +154,7 @@ theorem length_constraintTable_le [Fintype α] (table : α → α → Bool) : /-- Bounded growth per descriptor gives bounded total encoded growth. Both the inner edge encoding and the outer list framing are charged. -/ -theorem length_encoding_mapConstraints_le (g : Graph C) (f : C → C') (bound : ℕ) +private theorem length_encoding_mapConstraints_le (g : Graph C) (f : C → C') (bound : ℕ) (hf : ∀ c, (enc' (f c)).length ≤ (enc c).length + bound) : (encoding enc' (g.mapConstraints f)).length ≤ (encoding enc g).length + 2 * g.edges.length * bound := by diff --git a/Complexity/Computability/PCP/Encoded/DegreeReduction.lean b/Complexity/Computability/PCP/Encoded/DegreeReduction.lean index f0cb5f931..4d45c887b 100644 --- a/Complexity/Computability/PCP/Encoded/DegreeReduction.lean +++ b/Complexity/Computability/PCP/Encoded/DegreeReduction.lean @@ -203,7 +203,7 @@ variable (g : Graph C) (eval : C → α → α → Bool) (fallback : C) include hrotate in /-- Every computed destination agrees with the existing mathematical degree reduction. -/ -theorem dst_degreeReduceEdge (p : (Fin g.edges.length × Bool) × (Unit ⊕ D)) : +private theorem dst_degreeReduceEdge (p : (Fin g.edges.length × Bool) × (Unit ⊕ D)) : (g.degreeReduceEdge fallback rotate (numberDart p)).dst = let next := ((g.toGraph eval).degreeReduce (g.cloudFamily eval fallback family)).graph.neighbor @@ -216,7 +216,7 @@ theorem dst_degreeReduceEdge (p : (Fin g.edges.length × Bool) × (Unit ⊕ D)) ((g.toGraph eval).endpoint (i, b)) ⟨(i, b), rfl⟩ d) /-- Original constraints retain their orientation, while cloud-links are equality constraints. -/ -theorem rel_degreeReduceEdge [DecidableEq α] +private theorem rel_degreeReduceEdge [DecidableEq α] (p : (Fin g.edges.length × Bool) × (Unit ⊕ D)) (a b : α) : degreeReduceEval eval (g.degreeReduceEdge fallback rotate (numberDart p)).constraint a b = true ↔ diff --git a/Complexity/Computability/PCP/Encoded/Power.lean b/Complexity/Computability/PCP/Encoded/Power.lean index 51461535e..1405147fe 100644 --- a/Complexity/Computability/PCP/Encoded/Power.lean +++ b/Complexity/Computability/PCP/Encoded/Power.lean @@ -112,7 +112,7 @@ variable [DecidableEq α] (g : Graph C) (eval : C → α → α → Bool) (fallb include hrotate in /-- The executable destination is the numbered endpoint of the mathematical killed walk. -/ -theorem dst_powerPreprocessEdge +private theorem dst_powerPreprocessEdge (dart : (Fin g.edges.length × Bool) × PowerLabel D T q) : (g.powerPreprocessEdge eval fallback rotate T q ((dart.1.1.val, dart.1.2), dart.2)).dst = @@ -127,7 +127,7 @@ theorem dst_powerPreprocessEdge include hrotate in /-- Each computed Boolean table is exactly the mathematical powered relation. -/ -theorem rel_powerPreprocessEdge +private theorem rel_powerPreprocessEdge (dart : (Fin g.edges.length × Bool) × PowerLabel D T q) (a b : PowerAlphabet D α T) : (g.powerPreprocessEdge eval fallback rotate T q ((dart.1.1.val, dart.1.2), dart.2)).constraint a b = true ↔ diff --git a/Complexity/Computability/PCP/Encoded/Preprocess.lean b/Complexity/Computability/PCP/Encoded/Preprocess.lean index 38e44eb7f..86794987a 100644 --- a/Complexity/Computability/PCP/Encoded/Preprocess.lean +++ b/Complexity/Computability/PCP/Encoded/Preprocess.lean @@ -250,7 +250,7 @@ variable (g : Graph C) (eval : C → α → α → Bool) (fallback truth : C) include hrotate in /-- A numerical realization of rotations only emits endpoints among the declared vertices. -/ -theorem endpoints_rotationEdges (labels : List D) (vertices : ℕ) +private theorem endpoints_rotationEdges (labels : List D) (vertices : ℕ) (p : ℕ × ℕ) (hp : p ∈ rotationEdges rotate labels vertices) : p.1 < vertices ∧ p.2 < vertices := by obtain ⟨v, hv, hp⟩ := List.mem_flatMap.mp hp diff --git a/Complexity/Computability/PCP/Encoded/Preprocess/Programs.lean b/Complexity/Computability/PCP/Encoded/Preprocess/Programs.lean index 19de9649a..2cdc689c6 100644 --- a/Complexity/Computability/PCP/Encoded/Preprocess/Programs.lean +++ b/Complexity/Computability/PCP/Encoded/Preprocess/Programs.lean @@ -60,7 +60,7 @@ theorem halfEdgeOfNumber_halfEdgeNumber (p : ℕ × Bool) : cases b <;> simp [halfEdgeOfNumber, halfEdgeNumber, Nat.add_div, Nat.add_mod] /-- The executable inverse agrees with the finite half-edge numbering. -/ -theorem halfEdgeOfNumber_eq (edges : ℕ) (v : Fin (2 * edges)) : +private theorem halfEdgeOfNumber_eq (edges : ℕ) (v : Fin (2 * edges)) : halfEdgeOfNumber v.val = ((halfEdgeEquiv edges).symm v |>.1.val, ((halfEdgeEquiv edges).symm v).2) := by rw [← Equiv.apply_symm_apply (halfEdgeEquiv edges) v, halfEdgeEquiv_val, diff --git a/Complexity/Computability/PCP/Encoded/SelectedComposition/Enumeration.lean b/Complexity/Computability/PCP/Encoded/SelectedComposition/Enumeration.lean index 378a9bb8c..6a94670e5 100644 --- a/Complexity/Computability/PCP/Encoded/SelectedComposition/Enumeration.lean +++ b/Complexity/Computability/PCP/Encoded/SelectedComposition/Enumeration.lean @@ -87,7 +87,7 @@ theorem WellFormed.composeSelectedEnumerated {g : Graph (α → α → Bool)} (h SelectedHadamardTester.implementation.wellFormed_composeEnumerated hg /-- Complete enumeration realizes the exact selected-composition value. -/ -theorem unsatVal_composeSelectedEnumerated_eq (g : Graph (α → α → Bool)) : +private theorem unsatVal_composeSelectedEnumerated_eq (g : Graph (α → α → Bool)) : (g.composeSelectedEnumerated.toGraph id).unsatVal = (g.toGraph id).composeSelected.unsatVal := SelectedHadamardTester.implementation.unsatVal_composeEnumerated_eq SelectedHadamardTester.realizes_implementation g diff --git a/Complexity/Computability/PCP/Encoded/ThreeSAT.lean b/Complexity/Computability/PCP/Encoded/ThreeSAT.lean index 381665c82..dd72eb2ef 100644 --- a/Complexity/Computability/PCP/Encoded/ThreeSAT.lean +++ b/Complexity/Computability/PCP/Encoded/ThreeSAT.lean @@ -51,7 +51,7 @@ def clauseHolds (κ : Clause ℕ) (a : Fin 3 → Bool) : Bool := (List.finRange 3).any fun q => κ[q.val]?.elim false (fun l => a q == l.2) /-- The Boolean test agrees with the existing mathematical clause predicate. -/ -theorem clauseHolds_eq_true (κ : Clause ℕ) (a : Fin 3 → Bool) : +private theorem clauseHolds_eq_true (κ : Clause ℕ) (a : Fin 3 → Bool) : clauseHolds κ a = true ↔ ConstraintGraph.ClauseHolds κ a := by simp only [clauseHolds, List.any_eq_true, List.mem_finRange, true_and, ConstraintGraph.ClauseHolds] @@ -205,7 +205,7 @@ theorem satisfiable_ofCNF_iff (variableCount : ℕ) (φ : CNF ℕ) exact ConstraintGraph.satisfiable_ofCNF_iff φ h3 /-- Bounded variable names ensure every generated endpoint lies in the declared vertex range. -/ -theorem wellFormed_ofCNF (variableCount : ℕ) (φ : CNF ℕ) +private theorem wellFormed_ofCNF (variableCount : ℕ) (φ : CNF ℕ) (hvars : ∀ v ∈ φ.vars, v < variableCount) : (ofCNF variableCount φ).WellFormed := by intro e he obtain ⟨⟨j, q⟩, hp, rfl⟩ := List.mem_map.mp he diff --git a/Complexity/Computability/PCP/Encoded/Verifier/Soundness.lean b/Complexity/Computability/PCP/Encoded/Verifier/Soundness.lean index 0cd7bee84..9eeb2df2e 100644 --- a/Complexity/Computability/PCP/Encoded/Verifier/Soundness.lean +++ b/Complexity/Computability/PCP/Encoded/Verifier/Soundness.lean @@ -105,7 +105,7 @@ theorem rejectProb_edgeVerifier (width : ℕ) (decode : (Fin width → Bool) → labels] /-- Rounding the edge sampling range to a power of two loses at most half the rejection rate. -/ -theorem unsatFrac_div_two_le_rejectProb (width : ℕ) (decode : (Fin width → Bool) → α) +private theorem unsatFrac_div_two_le_rejectProb (width : ℕ) (decode : (Fin width → Bool) → α) (eval : C → α → α → Bool) (g : Graph C) (proof : List Bool) : (g.toGraph eval).unsatFrac (proofLabels width decode proof) / 2 ≤ (((BitString.uniformList (Nat.clog 2 g.edges.length)).map diff --git a/Complexity/Computability/PCP/Power.lean b/Complexity/Computability/PCP/Power.lean index d1bcddeac..03598b7c3 100644 --- a/Complexity/Computability/PCP/Power.lean +++ b/Complexity/Computability/PCP/Power.lean @@ -145,7 +145,7 @@ theorem take_congr {m m' : ℕ} (h : m = m') (hm : m ≤ T) (hm' : m' ≤ T) (k rfl /-- There are `∑ ℓ ≤ T, |D| ^ ℓ` walks of length at most `T` from a vertex. -/ -theorem card_eq [Fintype D] : +private theorem card_eq [Fintype D] : Fintype.card (WalkLabels D T) = ∑ ℓ ∈ range (T + 1), Fintype.card D ^ ℓ := by rw [Fintype.card_sigma, ← Fin.sum_univ_eq_sum_range] simp @@ -235,7 +235,7 @@ theorem rel_truthful_iff (σ : V → α) (p : V × (Fin T → D) × (Fin T → F variable {R T q} in /-- The truthful opinions of a labelling satisfying `R` satisfy the powered constraint graph. -/ -theorem satisfies_power_truthful {σ : V → α} (hσ : ∀ d, R.toConstraintGraph.Satisfies σ d) +private theorem satisfies_power_truthful {σ : V → α} (hσ : ∀ d, R.toConstraintGraph.Satisfies σ d) (p : V × (Fin T → D) × (Fin T → Fin q)) : (R.power T q).toConstraintGraph.Satisfies (R.truthful T σ) p := satisfies_power_iff.2 fun _ hi ↦ (R.rel_truthful_iff T q σ p hi).2 (hσ _) @@ -363,7 +363,7 @@ open Classical in /-- **Killed at a given step, a killed walk reports like a uniformly random walk**: a killed walk from `v` is killed at its step `ℓ < T` and reports `σ v` about `v` with probability `(1 - 1 / q) ^ ℓ / q` times the proportion of the walks of length `ℓ` from `v` that do. -/ -theorem expect_killTime_eq_and_report_eq [Nonempty D] (A : V → WalkLabels D T → α) +private theorem expect_killTime_eq_and_report_eq [Nonempty D] (A : V → WalkLabels D T → α) (σ : V → α) (v : V) {ℓ : ℕ} (hℓ : ℓ < T) : 𝔼 x : (Fin T → D) × (Fin T → Fin q), (if killTime x.2 = ℓ ∧ @@ -391,7 +391,8 @@ noncomputable def decode (A : V → WalkLabels D T → α) (v : V) : α := open Classical in /-- **Plurality**: the decoded label of `v` is reported about `v` by the far ends of a proportion at least `1 / |α|` of the killed walks from `v`. -/ -theorem inv_card_le_expect_report_eq_decode [Nonempty D] (A : V → WalkLabels D T → α) (v : V) : +private theorem inv_card_le_expect_report_eq_decode [Nonempty D] (A : V → WalkLabels D T → α) + (v : V) : (Fintype.card α : ℝ)⁻¹ ≤ 𝔼 x : (Fin T → D) × (Fin T → Fin q), if R.report T A (killTime_le x.2) (v, Fin.take _ (killTime_le x.2) x.1) = R.decode T q A v then 1 else 0 := by diff --git a/Complexity/Computability/PCP/PoweringBound.lean b/Complexity/Computability/PCP/PoweringBound.lean index 8bc3f0ca3..94fd40cc5 100644 --- a/Complexity/Computability/PCP/PoweringBound.lean +++ b/Complexity/Computability/PCP/PoweringBound.lean @@ -286,7 +286,7 @@ noncomputable def numHits (A : V → WalkLabels D T → α) (σ : V → α) open Classical in /-- The number of hits is the sum of the indicators of the hits at the steps before `T`. -/ -theorem numHits_eq_sum (A : V → WalkLabels D T → α) (σ : V → α) +private theorem numHits_eq_sum (A : V → WalkLabels D T → α) (σ : V → α) (p : V × (Fin T → D) × (Fin T → Fin q)) : (R.numHits T q A σ p : ℝ) = ∑ i ∈ range T, if R.Hit T q A σ p i then 1 else 0 := by rw [numHits, card_filter] @@ -510,7 +510,7 @@ theorem expect_numHits_sq_le (A : V → WalkLabels D T → α) (σ : V → α) open Classical in /-- A killed walk hit at some step is violated: the proportion of the killed walks hit at some step is at most the proportion of the darts of the powered constraint graph violated by `A`. -/ -theorem expect_numHits_ne_zero_le (A : V → WalkLabels D T → α) (σ : V → α) : +private theorem expect_numHits_ne_zero_le (A : V → WalkLabels D T → α) (σ : V → α) : 𝔼 p, (if (R.numHits T q A σ p : ℝ) = 0 then 0 else 1) ≤ (R.power T q).toConstraintGraph.unsatFrac A := by rw [← ConstraintGraph.expect_mem_unsatEdges] diff --git a/Complexity/Computability/PCP/ThreeSAT.lean b/Complexity/Computability/PCP/ThreeSAT.lean index 7586caebf..3a656e2c4 100644 --- a/Complexity/Computability/PCP/ThreeSAT.lean +++ b/Complexity/Computability/PCP/ThreeSAT.lean @@ -131,7 +131,7 @@ def cnfAssignment (A : V ⊕ Fin φ.length → Fin 3 → Bool) (x : V) : Bool := /-- A labelling satisfies the three edges of a clause only if the assignment it induces satisfies the clause. -/ -theorem eval_cnfAssignment_of_forall_satisfies {A : V ⊕ Fin φ.length → Fin 3 → Bool} +private theorem eval_cnfAssignment_of_forall_satisfies {A : V ⊕ Fin φ.length → Fin 3 → Bool} {j : Fin φ.length} (h : ∀ q, (ofCNF φ).Satisfies A (j, q)) : φ[j].eval (cnfAssignment A) = true := by obtain ⟨q, l, hl, hq⟩ := (h 0).1 @@ -157,7 +157,7 @@ theorem countUnsat_cnfAssignment_le_card_unsatEdges (A : V ⊕ Fin φ.length → variable (φ) /-- The labelling by an assignment satisfies the consistency part of every constraint. -/ -theorem cnfLabelling_consistent (τ : V → Bool) (e : Fin φ.length × Fin 3) : +private theorem cnfLabelling_consistent (τ : V → Bool) (e : Fin φ.length × Fin 3) : ∀ l, φ[e.1][e.2.val]? = some l → cnfLabelling φ τ (.inr e.1) e.2 = cnfLabelling φ τ ((ofCNF φ).dst e) 0 := by intro l hl @@ -166,7 +166,7 @@ theorem cnfLabelling_consistent (τ : V → Bool) (e : Fin φ.length × Fin 3) : /-- If the clauses of `φ` have at most three literals, the labelling by an assignment satisfies every edge of a clause that the assignment satisfies. -/ -theorem satisfies_cnfLabelling (h3 : ∀ c ∈ φ, c.length ≤ 3) {τ : V → Bool} +private theorem satisfies_cnfLabelling (h3 : ∀ c ∈ φ, c.length ≤ 3) {τ : V → Bool} {e : Fin φ.length × Fin 3} (he : φ[e.1].eval τ = true) : (ofCNF φ).Satisfies (cnfLabelling φ τ) e := by refine ⟨?_, cnfLabelling_consistent φ τ e⟩ @@ -209,12 +209,12 @@ theorem satisfiable_ofCNF_iff (h3 : ∀ c ∈ φ, c.length ≤ 3) : exact (CNF.eval_eq_true_iff _ _).1 hτ _ (List.getElem_mem _) /-- The constraint graph of a formula with `m` clauses has `3 m` edges. -/ -theorem card_edges_ofCNF : Fintype.card (Fin φ.length × Fin 3) = 3 * φ.length := by +private theorem card_edges_ofCNF : Fintype.card (Fin φ.length × Fin 3) = 3 * φ.length := by simp [mul_comm] /-- **Soundness**: a labelling violates at least a third of the proportion of clauses that the assignment read off from it falsifies. -/ -theorem countUnsat_div_le_unsatFrac (A : V ⊕ Fin φ.length → Fin 3 → Bool) : +private theorem countUnsat_div_le_unsatFrac (A : V ⊕ Fin φ.length → Fin 3 → Bool) : (φ.countUnsat (cnfAssignment A) : ℝ) / φ.length / 3 ≤ (ofCNF φ).unsatFrac A := by rw [unsatFrac, card_edges_ofCNF, Nat.cast_mul, div_div, mul_comm (φ.length : ℝ), Nat.cast_ofNat] gcongr diff --git a/Complexity/Computability/QueryComplexity/Relations.lean b/Complexity/Computability/QueryComplexity/Relations.lean index d844ec2c6..ddc520276 100644 --- a/Complexity/Computability/QueryComplexity/Relations.lean +++ b/Complexity/Computability/QueryComplexity/Relations.lean @@ -82,7 +82,8 @@ open Finset BitString variable {n : ℕ} /-- Flipping the coordinates on which `y` differs from `x` turns `x` into `y`. -/ -theorem BitString.flipBlock_filter_ne (x y : BitString n) : flipBlock {i | y i ≠ x i} x = y := by +private theorem BitString.flipBlock_filter_ne (x y : BitString n) : flipBlock + {i | y i ≠ x i} x = y := by funext i by_cases h : y i = x i · rw [flipBlock_apply_of_notMem (by simpa using h), h] @@ -236,7 +237,8 @@ theorem certificateComplexityFor_le_sensitivityFor_mul_blockSensitivityFor /-! ### Restricting by the answers to a certificate -/ /-- Restricting by answers on `S` does not raise `C_b(f)`. -/ -theorem certificateComplexityFor_comp_piecewise_le (f : BooleanFunction n) (S : Finset (Fin n)) +private theorem certificateComplexityFor_comp_piecewise_le (f : BooleanFunction n) + (S : Finset (Fin n)) (a : BitString n) (b : Bool) : certificateComplexityFor (fun y => f (S.piecewise a y)) b ≤ certificateComplexityFor f b := Finset.sup_le fun z hz => by @@ -255,7 +257,7 @@ private theorem piecewise_flipBlock (S B : Finset (Fin n)) (a z : BitString n) : /-- After restricting by the answers `a` to a certificate `S` of an input `w` of value `1`, every input `z` of value `0` has one sensitive block fewer than the filled input in the original function: the coordinates of `S` on which the filled input differs from `w`. -/ -theorem blockSensitivityAt_comp_piecewise_add_one_le {w : BitString n} {S : Finset (Fin n)} +private theorem blockSensitivityAt_comp_piecewise_add_one_le {w : BitString n} {S : Finset (Fin n)} (hS : IsCertificate f w S) (hw : f w = true) (a z : BitString n) (hz : f (S.piecewise a z) = false) : blockSensitivityAt (fun y => f (S.piecewise a y)) z + 1 ≤ @@ -307,7 +309,7 @@ theorem blockSensitivityAt_comp_piecewise_add_one_le {w : BitString n} {S : Fins rwa [card_insert_of_notMem hB₀F, card_image_of_injOn hinj, ← hFcard] at this /-- Restricting by the answers to a certificate of an input of value `1` lowers `bs₀(f)`. -/ -theorem blockSensitivityFor_comp_piecewise_false_le {w : BitString n} {S : Finset (Fin n)} +private theorem blockSensitivityFor_comp_piecewise_false_le {w : BitString n} {S : Finset (Fin n)} (hS : IsCertificate f w S) (hw : f w = true) (a : BitString n) {m : ℕ} (hm : blockSensitivityFor f false ≤ m + 1) : blockSensitivityFor (fun y => f (S.piecewise a y)) false ≤ m := diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Basic.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Basic.lean index 9a8f71289..a452d58f5 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Basic.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Basic.lean @@ -103,7 +103,7 @@ section Finite variable [Fintype I] /-- Flipping `x` on the set of coordinates where `x` and `y` differ yields `y`. -/ -theorem flip_differences (x y : I → Bool) : +private theorem flip_differences (x y : I → Bool) : flip x (Finset.univ.filter fun i => x i ≠ y i) = y := by funext i cases hx : x i <;> cases hy : y i <;> simp [flip_apply, hx, hy] @@ -230,7 +230,7 @@ omit [Fintype I] in open scoped Classical in /-- Over a finite index type, a function invariant under every single-coordinate flip is constant. -/ -theorem eq_of_singleton_invariant [Finite I] (f : (I → Bool) → Bool) +private theorem eq_of_singleton_invariant [Finite I] (f : (I → Bool) → Bool) (h : ∀ x i, f (flip x {i}) = f x) (x y : I → Bool) : f x = f y := by have := Fintype.ofFinite I have hflip (B : Finset I) : f (flip x B) = f x := by diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Bridge.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Bridge.lean index 83883a98d..4dd3bbd30 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Bridge.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Bridge.lean @@ -51,12 +51,12 @@ theorem flip_eq_flipOn {I : Type} [DecidableEq I] (x : I → Bool) (B : Finset I exact Subsingleton.elim _ _ /-- On `Fin n`, the internal flip is CSLib's `BitString.flipBlock`. -/ -theorem flip_eq_flipBlock (x : BitString n) (B : Finset (Fin n)) : +private theorem flip_eq_flipBlock (x : BitString n) (B : Finset (Fin n)) : flip x B = BitString.flipBlock B x := flip_eq_flipOn x B /-- On `Fin n`, the internal pointwise sensitivity is `BitString.sensitivityAt`. -/ -theorem sensitivityAt_eq_bitString_sensitivityAt (f : BooleanFunction n) (x : BitString n) : +private theorem sensitivityAt_eq_bitString_sensitivityAt (f : BooleanFunction n) (x : BitString n) : sensitivityAt f x = BitString.sensitivityAt f x := by unfold sensitivityAt BitString.sensitivityAt BitString.sensitiveCoords congr 1 diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Composition.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Composition.lean index 26b3f670c..4a890695c 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Composition.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Composition.lean @@ -97,7 +97,7 @@ theorem compose_zero (f : (I → Bool) → Bool) (g : (J → Bool) → Bool) /-- If `g` rejects the all-false input and flipping the block `D` changes its value there, then flipping the product block `C ×ˢ D` in the all-false input of `compose f g` gives the value of `f` on the all-false input with `C` flipped. -/ -theorem compose_flip_product_zero (f : (I → Bool) → Bool) (g : (J → Bool) → Bool) +private theorem compose_flip_product_zero (f : (I → Bool) → Bool) (g : (J → Bool) → Bool) (C : Finset I) (D : Finset J) (hg : g (fun _ => false) = false) (hD : g (flip (fun _ => false) D) ≠ g (fun _ => false)) : compose f g (flip (fun _ => false) (C ×ˢ D)) = f (flip (fun _ => false) C) := by diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Construction.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Construction.lean index dc2946c43..eb0f8146a 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Construction.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Construction.lean @@ -78,13 +78,13 @@ def terminalPredicate {M r : ℕ} (d : ℕ) (T : RegularTournament M) towerFamily T.toTournament A.label (constructionBase d M) d 1 0 /-- The base family at index count `d + 1` is nested. -/ -theorem construction_base_nested (d M : ℕ) : +private theorem construction_base_nested (d M : ℕ) : NestedFamily (constructionBase d M (d + 1)) := by simpa only [constructionBase, baseExtension_same] using initialFamily_nested d M /-- Every predicate of the base family at index count `1 + d` rejects the all-false input. -/ -theorem construction_base_zero (d M : ℕ) : +private theorem construction_base_zero (d M : ℕ) : ∀ q, constructionBase d M (1 + d) q (fun _ => false) = false := by rw [Nat.add_comm 1 d] simpa only [constructionBase, baseExtension_same] using @@ -92,7 +92,7 @@ theorem construction_base_zero (d M : ℕ) : /-- Every predicate of the base family at index count `1 + d` accepts the all-false input with any row block `baseBlock b` flipped. -/ -theorem construction_base_blocks (d M : ℕ) : +private theorem construction_base_blocks (d M : ℕ) : ∀ b q, constructionBase d M (1 + d) q (flip (fun _ => false) (baseBlock b)) = true := by rw [Nat.add_comm 1 d] @@ -101,7 +101,7 @@ theorem construction_base_blocks (d M : ℕ) : initialFamily_baseBlock d M q b /-- For `0 < r`, the terminal predicate rejects the all-false input. -/ -theorem terminalPredicate_zero {M r : ℕ} (d : ℕ) (T : RegularTournament M) +private theorem terminalPredicate_zero {M r : ℕ} (d : ℕ) (T : RegularTournament M) (A : GoodLabeling T.toTournament r) (hr : 0 < r) : terminalPredicate d T A (fun _ => false) = false := towerFamily_zero T.toTournament A.label (constructionBase d M) hr d 1 @@ -109,7 +109,7 @@ theorem terminalPredicate_zero {M r : ℕ} (d : ℕ) (T : RegularTournament M) /-- For `0 < r`, the terminal predicate accepts the all-false input with any lifted base block `towerBlocks baseBlock d b` flipped. -/ -theorem terminalPredicate_blocks {M r : ℕ} (d : ℕ) (T : RegularTournament M) +private theorem terminalPredicate_blocks {M r : ℕ} (d : ℕ) (T : RegularTournament M) (A : GoodLabeling T.toTournament r) (hr : 0 < r) (b : TowerBlockIndex (2 * M ^ 2 + 1) (Fin M) d) : terminalPredicate d T A (flip (fun _ => false) @@ -163,7 +163,7 @@ theorem construction_profiles {M r : ℕ} (d : ℕ) (T : RegularTournament M) /-- Under the budget `max r 16 / M * 3 ^ (d + 1) ≤ 2`, the terminal predicate has sensitivity at most `2 * (d + 2) * M ^ d` at every rejected input and at most `2 * (d + 2) * M ^ (d + 1)` at every accepted input. -/ -theorem terminalPredicate_sensitivityAt {M r : ℕ} (d : ℕ) (T : RegularTournament M) +private theorem terminalPredicate_sensitivityAt {M r : ℕ} (d : ℕ) (T : RegularTournament M) (A : GoodLabeling T.toTournament r) (hM : 0 < M) (hr : 0 < r) (hbudget : ((max r 16 : ℕ) : ℝ) / M * 3 ^ (d + 1) ≤ 2) : (∀ x, terminalPredicate d T A x = false → @@ -183,14 +183,14 @@ def finalBoolean {M r : ℕ} (d : ℕ) (T : RegularTournament M) orCopies (K := Fin M) (terminalPredicate d T A) /-- For `0 < r`, the final Boolean function rejects the all-false input. -/ -theorem finalBoolean_zero {M r : ℕ} (d : ℕ) (T : RegularTournament M) +private theorem finalBoolean_zero {M r : ℕ} (d : ℕ) (T : RegularTournament M) (A : GoodLabeling T.toTournament r) (hr : 0 < r) : finalBoolean d T A (fun _ => false) = false := orCopies_zero _ (terminalPredicate_zero d T A hr) /-- Under the budget `max r 16 / M * 3 ^ (d + 1) ≤ 2`, `sensitivity (finalBoolean d T A) ≤ 2 * (d + 2) * M ^ (d + 1)`. -/ -theorem finalBoolean_sensitivity {M r : ℕ} (d : ℕ) (T : RegularTournament M) +private theorem finalBoolean_sensitivity {M r : ℕ} (d : ℕ) (T : RegularTournament M) (A : GoodLabeling T.toTournament r) (hM : 0 < M) (hr : 0 < r) (hbudget : ((max r 16 : ℕ) : ℝ) / M * 3 ^ (d + 1) ≤ 2) : sensitivity (finalBoolean d T A) ≤ 2 * (d + 2) * M ^ (d + 1) := by @@ -201,7 +201,7 @@ theorem finalBoolean_sensitivity {M r : ℕ} (d : ℕ) (T : RegularTournament M) /-- For `0 < r`, the final Boolean function has block sensitivity at least `M ^ 2 * (2 * M ^ 2 + 1) ^ d` at the all-false input. -/ -theorem finalBoolean_blockSensitivity {M r : ℕ} (d : ℕ) (T : RegularTournament M) +private theorem finalBoolean_blockSensitivity {M r : ℕ} (d : ℕ) (T : RegularTournament M) (A : GoodLabeling T.toTournament r) (hr : 0 < r) : M ^ 2 * (2 * M ^ 2 + 1) ^ d ≤ blockSensitivityAt (finalBoolean d T A) (fun _ => false) := by have h := (Nat.mul_le_mul_left M (terminalPredicate_blockSensitivity d T A hr)).trans diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/HammingBase.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/HammingBase.lean index ff00daa59..1df39bb90 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/HammingBase.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/HammingBase.lean @@ -56,7 +56,7 @@ variable {I C : Type} [Fintype I] open scoped Classical in /-- Flipping one coordinate yields an input at Hamming distance `1` from the original. -/ -theorem hammingDist_flip_self (x : I → Bool) (i : I) : +private theorem hammingDist_flip_self (x : I → Bool) (i : I) : hammingDist x (flip x {i}) = 1 := by have h : (Finset.univ.filter fun j => x j ≠ flip x {i} j) = {i} := by ext j @@ -69,7 +69,7 @@ theorem hammingDist_flip_self (x : I → Bool) (i : I) : /-- A one-bit flip decreases the Hamming distance to any `z` by at most one: `hammingDist x z ≤ hammingDist (flip x {i}) z + 1`. -/ -theorem hammingDist_le_flip_add_one (x z : I → Bool) (i : I) : +private theorem hammingDist_le_flip_add_one (x z : I → Bool) (i : I) : hammingDist x z ≤ hammingDist (flip x {i}) z + 1 := by have h := hammingDist_triangle x (flip x {i}) z rw [hammingDist_flip_self] at h @@ -77,7 +77,7 @@ theorem hammingDist_le_flip_add_one (x z : I → Bool) (i : I) : /-- A one-bit flip increases the Hamming distance to any `z` by at most one: `hammingDist (flip x {i}) z ≤ hammingDist x z + 1`. -/ -theorem hammingDist_flip_le_add_one (x z : I → Bool) (i : I) : +private theorem hammingDist_flip_le_add_one (x z : I → Bool) (i : I) : hammingDist (flip x {i}) z ≤ hammingDist x z + 1 := by have h := hammingDist_triangle (flip x {i}) x z rw [hammingDist_comm (flip x {i}) x, hammingDist_flip_self] at h @@ -121,7 +121,7 @@ theorem ballPredicate_nested [Fintype C] (centers : C → I → Bool) /-- If `x` is rejected at radius `R` but `flip x {i}` is accepted, then some center is at Hamming distance exactly `R + 1` from `x` and differs from `x` at coordinate `i`. -/ -theorem ballPredicate_zero_flip [Fintype C] (centers : C → I → Bool) (R : ℕ) +private theorem ballPredicate_zero_flip [Fintype C] (centers : C → I → Bool) (R : ℕ) (x : I → Bool) (i : I) (hx : ballPredicate centers R x = false) (hi : ballPredicate centers R (flip x {i}) = true) : ∃ c, hammingDist x (centers c) = R + 1 ∧ x i ≠ centers c i := by diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/InitialPredicates.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/InitialPredicates.lean index 6f4c52211..c56250f77 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/InitialPredicates.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/InitialPredicates.lean @@ -65,7 +65,7 @@ def baseBlock {M L : ℕ} (j : Fin M) : Finset (Fin M × Fin L) := simp [baseBlock] /-- Each row `baseBlock j` of `Fin M × Fin L` has exactly `L` coordinates. -/ -theorem baseBlock_card {M L : ℕ} (j : Fin M) : (baseBlock (L := L) j).card = L := by +private theorem baseBlock_card {M L : ℕ} (j : Fin M) : (baseBlock (L := L) j).card = L := by have h : (baseBlock (L := L) j).card = (Finset.univ : Finset (Fin L)).card := by apply Finset.card_bij (fun p _ => p.2) · intro p _ @@ -92,14 +92,14 @@ theorem baseBlock_disjoint {M L : ℕ} : exact hij (hi.symm.trans hj) /-- Flipping row `j` of the all-`false` input yields `blockCenter j`. -/ -theorem flip_zero_baseBlock {M L : ℕ} (j : Fin M) : +private theorem flip_zero_baseBlock {M L : ℕ} (j : Fin M) : flip (fun _ : Fin M × Fin L => false) (baseBlock j) = blockCenter j := by ext p simp [flip_apply, blockCenter] /-- Each row center `blockCenter j` is at Hamming distance `L` from the all-`false` input. -/ -theorem hammingDist_zero_blockCenter {M L : ℕ} (j : Fin M) : +private theorem hammingDist_zero_blockCenter {M L : ℕ} (j : Fin M) : hammingDist (fun _ : Fin M × Fin L => false) (blockCenter j) = L := by have hs : (Finset.univ.filter fun p : Fin M × Fin L => false ≠ blockCenter j p) = baseBlock j := by @@ -108,7 +108,7 @@ theorem hammingDist_zero_blockCenter {M L : ℕ} (j : Fin M) : rw [hammingDist, hs, baseBlock_card] /-- Distinct row centers are at Hamming distance `2 * L`. -/ -theorem hammingDist_blockCenter {M L : ℕ} (i j : Fin M) (hij : i ≠ j) : +private theorem hammingDist_blockCenter {M L : ℕ} (i j : Fin M) (hij : i ≠ j) : hammingDist (blockCenter (L := L) i) (blockCenter j) = 2 * L := by have hs : (Finset.univ.filter fun p : Fin M × Fin L => blockCenter i p ≠ blockCenter j p) = diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Iterates.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Iterates.lean index 9bee9730d..ecb7beee3 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Iterates.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Iterates.lean @@ -70,7 +70,7 @@ def iterateCompose {I : Type} (f : (I → Bool) → Bool) : | m + 1 => compose f (iterateCompose f m) /-- If `f` rejects the all-false input, then so does every iterate `iterateCompose f m`. -/ -theorem iterateCompose_zero {I : Type} (f : (I → Bool) → Bool) +private theorem iterateCompose_zero {I : Type} (f : (I → Bool) → Bool) (hf : f (fun _ => false) = false) (m : ℕ) : iterateCompose f m (fun _ => false) = false := by induction m with @@ -89,7 +89,7 @@ theorem iterateCoord_card (m : ℕ) : rw [Fintype.card_prod, ih, pow_succ, Nat.mul_comm] /-- Sensitivity of iterates: `sensitivity (iterateCompose f m) ≤ sensitivity f ^ m`. -/ -theorem sensitivity_iterateCompose_le (f : (I → Bool) → Bool) (m : ℕ) : +private theorem sensitivity_iterateCompose_le (f : (I → Bool) → Bool) (m : ℕ) : sensitivity (iterateCompose f m) ≤ sensitivity f ^ m := by induction m with | zero => @@ -105,7 +105,7 @@ theorem sensitivity_iterateCompose_le (f : (I → Bool) → Bool) (m : ℕ) : /-- If `f` rejects the all-false input, then the `m`-th power of its block sensitivity at the all-false input is at most the block sensitivity of `iterateCompose f m` there. -/ -theorem blockSensitivityAt_iterateCompose_zero (f : (I → Bool) → Bool) +private theorem blockSensitivityAt_iterateCompose_zero (f : (I → Bool) → Bool) (hf : f (fun _ => false) = false) (m : ℕ) : blockSensitivityAt f (fun _ => false) ^ m ≤ blockSensitivityAt (iterateCompose f m) (fun _ => false) := by diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/LabelingEstimate.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/LabelingEstimate.lean index 5ff6e9ed1..5d4740535 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/LabelingEstimate.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/LabelingEstimate.lean @@ -39,7 +39,7 @@ namespace Cslib.QueryComplexity.SensitivitySeparation namespace Internal /-- If `3 ≤ M` and `M ≤ r ^ 2`, then `(2 * M ^ 2 + 1) ^ 16 * M ^ 20 ≤ 3 ^ 16 * r ^ 104`. -/ -theorem labeling_union_bound_numerator {M r : ℕ} (hM : 3 ≤ M) (hMr : M ≤ r ^ 2) : +private theorem labeling_union_bound_numerator {M r : ℕ} (hM : 3 ≤ M) (hMr : M ≤ r ^ 2) : (2 * M ^ 2 + 1) ^ 16 * M ^ 20 ≤ 3 ^ 16 * r ^ 104 := by have hk : 2 * M ^ 2 + 1 ≤ 3 * M ^ 2 := by nlinarith have hp : M ^ 52 ≤ r ^ 104 := by @@ -53,7 +53,7 @@ theorem labeling_union_bound_numerator {M r : ℕ} (hM : 3 ≤ M) (hMr : M ≤ r _ ≤ 3 ^ 16 * r ^ 104 := Nat.mul_le_mul_left _ hp /-- For `3 ≤ M`, `3 ^ 16 < M ^ 20`. -/ -theorem labeling_union_bound_constant {M : ℕ} (hM : 3 ≤ M) : +private theorem labeling_union_bound_constant {M : ℕ} (hM : 3 ≤ M) : 3 ^ 16 < M ^ 20 := by calc 3 ^ 16 ≤ M ^ 16 := Nat.pow_le_pow_left hM 16 @@ -88,7 +88,7 @@ theorem labeling_union_bound_real {M r : ℕ} (hM : 3 ≤ M) (hMr : M ≤ r ^ 2) exact_mod_cast labeling_union_bound_constant hM /-- For `0 < M`, `(3 * M ^ 2) ^ 16 / (Real.sqrt M) ^ 104 = 3 ^ 16 / M ^ 20`. -/ -theorem labeling_sqrt_expression {M : ℕ} (hM : 0 < M) : +private theorem labeling_sqrt_expression {M : ℕ} (hM : 0 < M) : (3 * (M : ℝ) ^ 2) ^ 16 / (Real.sqrt M) ^ 104 = 3 ^ 16 / (M : ℝ) ^ 20 := by have hp : (0 : ℝ) < M := by exact_mod_cast hM have hd : (Real.sqrt M) ^ 104 = (M : ℝ) ^ 52 := by diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/LabelingEvents.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/LabelingEvents.lean index 352d5c27a..1c601d4e4 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/LabelingEvents.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/LabelingEvents.lean @@ -70,7 +70,7 @@ theorem mem_labelingEvent_iff {v : Fin n → Fin k} {m : Fin n → Fin r} open scoped Classical in /-- For injective `v`, the labeling event is the set of labelings taking the value `m (Function.invFun v p.2)` on every internal edge `p` of the image of `v`. -/ -theorem labelingEvent_eq [NeZero n] (v : Fin n → Fin k) (m : Fin n → Fin r) +private theorem labelingEvent_eq [NeZero n] (v : Fin n → Fin k) (m : Fin n → Fin r) (hv : Function.Injective v) : T.labelingEvent v m = Finset.univ.filter fun A => ∀ p ∈ T.internalEdges (Finset.univ.image v), A p = m (Function.invFun v p.2) := by @@ -98,7 +98,7 @@ theorem card_labelingEvent [NeZero n] (v : Fin n → Fin k) (m : Fin n → Fin r open scoped Classical in /-- Every labeling event has at most `r ^ (k * k - n.choose 2)` elements; it is empty when `v` is not injective. -/ -theorem card_labelingEvent_le [NeZero n] (v : Fin n → Fin k) (m : Fin n → Fin r) : +private theorem card_labelingEvent_le [NeZero n] (v : Fin n → Fin k) (m : Fin n → Fin r) : (T.labelingEvent v m).card ≤ r ^ (k * k-n.choose 2) := by by_cases hv : Function.Injective v · exact (T.card_labelingEvent v m hv).le diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Or.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Or.lean index b4cfacff8..d699d796c 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Or.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Or.lean @@ -68,7 +68,7 @@ def orBits (x : K → Bool) : Bool := decide (∃ k, x k = true) /-- If some coordinate `j ≠ i` of `x` is true, then flipping coordinate `i` does not change `orBits x`. -/ -theorem orBits_flip_of_witness (x : K → Bool) {i j : K} +private theorem orBits_flip_of_witness (x : K → Bool) {i j : K} (hji : j ≠ i) (hj : x j = true) : orBits (flip x {i}) = orBits x := by have h₁ : orBits x = true := (orBits_eq_true x).mpr ⟨j, hj⟩ have h₂ : orBits (flip x {i}) = true := diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/ParameterBounds.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/ParameterBounds.lean index ab197f0f8..57e98d62f 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/ParameterBounds.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/ParameterBounds.lean @@ -64,7 +64,7 @@ theorem ceil_sqrt_max_le_two_sqrt {M : ℕ} (hM : 81 ≤ M) : exact max_le (by linarith) (by linarith) /-- If `9 ^ (d + 1) ≤ M`, then `3 ^ (d + 1) ≤ Real.sqrt M`. -/ -theorem parameter_sqrt_lower {d M : ℕ} (hM : 9 ^ (d + 1) ≤ M) : +private theorem parameter_sqrt_lower {d M : ℕ} (hM : 9 ^ (d + 1) ≤ M) : (3 : ℝ) ^ (d + 1) ≤ Real.sqrt (M : ℝ) := by apply Real.le_sqrt_of_sq_le calc diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/RecursiveBlocks.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/RecursiveBlocks.lean index e7ce2e453..f52e05f5d 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/RecursiveBlocks.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/RecursiveBlocks.lean @@ -83,14 +83,14 @@ theorem rowLift_nonempty {k r : ℕ} {I : Type} (i : Fin k) (B : Finset I) exact ⟨((i, ⟨0, hr⟩), a), (mem_rowLift i B _).mpr ⟨rfl, ha⟩⟩ /-- Blocks lifted to distinct rows are disjoint. -/ -theorem rowLift_disjoint_of_ne {k r : ℕ} {I : Type} (i j : Fin k) +private theorem rowLift_disjoint_of_ne {k r : ℕ} {I : Type} (i j : Fin k) (B C : Finset I) (hij : i ≠ j) : Disjoint (rowLift (r := r) i B) (rowLift j C) := by apply Finset.disjoint_left.mpr intro p hp hq exact hij (((mem_rowLift i B p).mp hp).1.symm.trans ((mem_rowLift j C p).mp hq).1) /-- Lifts of disjoint child blocks are disjoint, whichever rows they are lifted to. -/ -theorem rowLift_disjoint {k r : ℕ} {I : Type} (i j : Fin k) (B C : Finset I) +private theorem rowLift_disjoint {k r : ℕ} {I : Type} (i j : Fin k) (B C : Finset I) (hBC : Disjoint B C) : Disjoint (rowLift (r := r) i B) (rowLift j C) := by apply Finset.disjoint_left.mpr intro p hp hq @@ -113,7 +113,7 @@ theorem rowLift_family_disjoint {k r : ℕ} {I K : Type} (blocks : K → Finset /-- After flipping `rowLift i B` in the all-false input, every child of row `i` is the all-false child input with `B` flipped. -/ -theorem recursiveChild_rowLift_same {k r : ℕ} {I : Type} +private theorem recursiveChild_rowLift_same {k r : ℕ} {I : Type} (i : Fin k) (B : Finset I) (c : Fin r) : recursiveChild (flip (fun _ => false) (rowLift (r := r) i B)) i c = flip (fun _ => false) B := by @@ -122,7 +122,7 @@ theorem recursiveChild_rowLift_same {k r : ℕ} {I : Type} /-- After flipping `rowLift i B` in the all-false input, every child outside row `i` is still all-false. -/ -theorem recursiveChild_rowLift_other {k r : ℕ} {I : Type} +private theorem recursiveChild_rowLift_other {k r : ℕ} {I : Type} (i j : Fin k) (B : Finset I) (c : Fin r) (hji : j ≠ i) : recursiveChild (flip (fun _ => false) (rowLift (r := r) i B)) j c = fun _ => false := by diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/RecursiveFlips.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/RecursiveFlips.lean index ecc3bacc8..30282e56e 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/RecursiveFlips.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/RecursiveFlips.lean @@ -61,7 +61,7 @@ theorem recursiveChild_flip_other {k r : ℕ} {I : Type} /-- If `x` and `y` give the same target values on all children of row `i` and the same gate values on the children `(j, label i j)` for all out-neighbours `j` of `i`, then the clause of row `i` takes the same value at `x` and `y`. -/ -theorem rowClause_eq_of_conditions {k r h : ℕ} {I : Type} (T : Tournament k) +private theorem rowClause_eq_of_conditions {k r h : ℕ} {I : Type} (T : Tournament k) (label : Fin k → Fin k → Fin r) (F : Fin (h + 1) → (I → Bool) → Bool) (q : Fin h) (x y : ((Fin k × Fin r) × I) → Bool) (i : Fin k) (ht : ∀ c, F (Fin.last h) (recursiveChild x i c) = diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Reindex.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Reindex.lean index 1d93909ac..c7379fb1c 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Reindex.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/Reindex.lean @@ -55,7 +55,7 @@ def reindex (e : I ≃ J) (f : (I → Bool) → Bool) : (J → Bool) → Bool := open scoped Classical in /-- Pulling back along `e` the input `x` with the image block `B.map e.toEmbedding` flipped gives the pullback `fun i => x (e i)` with `B` flipped. -/ -theorem flip_reindex (e : I ≃ J) (x : J → Bool) (B : Finset I) : +private theorem flip_reindex (e : I ≃ J) (x : J → Bool) (B : Finset I) : (fun i => flip x (B.map e.toEmbedding) (e i)) = flip (fun i => x (e i)) B := by funext i @@ -63,7 +63,7 @@ theorem flip_reindex (e : I ≃ J) (x : J → Bool) (B : Finset I) : /-- Singleton case of `flip_reindex`: pulling back `flip x {e i}` along `e` gives the pullback of `x` with `i` flipped. -/ -theorem flip_reindex_singleton (e : I ≃ J) (x : J → Bool) (i : I) : +private theorem flip_reindex_singleton (e : I ≃ J) (x : J → Bool) (i : I) : (fun a => flip x {e i} (e a)) = flip (fun a => x (e a)) {i} := by simpa using flip_reindex e x {i} @@ -107,7 +107,7 @@ theorem sensitivity_reindex (e : I ≃ J) (f : (I → Bool) → Bool) : /-- The block sensitivity of `f` at the pullback `fun i => x (e i)` is at most the block sensitivity of `reindex e f` at `x`. -/ -theorem blockSensitivityAt_le_reindex (e : I ≃ J) (f : (I → Bool) → Bool) +private theorem blockSensitivityAt_le_reindex (e : I ≃ J) (f : (I → Bool) → Bool) (x : J → Bool) : blockSensitivityAt f (fun i => x (e i)) ≤ blockSensitivityAt (reindex e f) x := by apply blockSensitivityAt_le diff --git a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/SeparationArithmetic.lean b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/SeparationArithmetic.lean index 047d8ccd0..0f4436b04 100644 --- a/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/SeparationArithmetic.lean +++ b/Complexity/Computability/QueryComplexity/SensitivitySeparation/Internal/SeparationArithmetic.lean @@ -56,7 +56,7 @@ namespace Internal /-- For `L ≠ 0` and `M ≠ 0`, `(M ^ 2 * k ^ d) / (2 * L * M ^ (d + 1)) ^ 2 = (k / M ^ 2) ^ d / (4 * L ^ 2)`. -/ -theorem seed_ratio_identity (d : ℕ) {L M k : ℝ} (hL : L ≠ 0) (hM : M ≠ 0) : +private theorem seed_ratio_identity (d : ℕ) {L M k : ℝ} (hL : L ≠ 0) (hM : M ≠ 0) : (M ^ 2 * k ^ d) / (2 * L * M ^ (d + 1)) ^ 2 = (k / M ^ 2) ^ d / (4 * L ^ 2) := by have hp : (M ^ 2) ^ d = (M ^ d) ^ 2 := by @@ -67,7 +67,7 @@ theorem seed_ratio_identity (d : ℕ) {L M k : ℝ} (hL : L ≠ 0) (hM : M ≠ 0 /-- For `0 < M`, `2 ^ d / (4 * (d + 2) ^ 2) ≤ (M ^ 2 * (2 * M ^ 2 + 1) ^ d) / (2 * (d + 2) * M ^ (d + 1)) ^ 2`. -/ -theorem seed_ratio_lower (d : ℕ) {M : ℝ} (hM : 0 < M) : +private theorem seed_ratio_lower (d : ℕ) {M : ℝ} (hM : 0 < M) : (2 : ℝ) ^ d / (4 * ((d : ℝ) + 2) ^ 2) ≤ (M ^ 2 * (2 * M ^ 2 + 1) ^ d) / (2 * ((d : ℝ) + 2) * M ^ (d + 1)) ^ 2 := by @@ -79,7 +79,7 @@ theorem seed_ratio_lower (d : ℕ) {M : ℝ} (hM : 0 < M) : /-- If `0 < sensitivity f ≤ s` and `0 ≤ b ≤ blockSensitivityAt f (fun _ => false)`, then `b / s ^ 2 ≤ blockSensitivityAt f (fun _ => false) / sensitivity f ^ 2`. -/ -theorem ratio_of_bounds {I : Type} [Fintype I] (f : (I → Bool) → Bool) +private theorem ratio_of_bounds {I : Type} [Fintype I] (f : (I → Bool) → Bool) (s b : ℝ) (hpos : 0 < (sensitivity f : ℝ)) (hs : (sensitivity f : ℝ) ≤ s) (hb : b ≤ (blockSensitivityAt f (fun _ => false) : ℝ)) (hb0 : 0 ≤ b) : diff --git a/Complexity/Computability/TreeEval/Ary/CookMertz.lean b/Complexity/Computability/TreeEval/Ary/CookMertz.lean index a5c7a7b04..9a15a0468 100644 --- a/Complexity/Computability/TreeEval/Ary/CookMertz.lean +++ b/Complexity/Computability/TreeEval/Ary/CookMertz.lean @@ -66,7 +66,7 @@ abbrev State (K : Type*) (d ℓ : ℕ) := Fin (d + 1) → Fin ℓ → K /-- The register of child `j` when the target register is `t`. -/ def reg (t : Fin (d + 1)) (j : Fin d) : Fin (d + 1) := t + j.succ -theorem reg_ne (t : Fin (d + 1)) (j : Fin d) : reg t j ≠ t := by +private theorem reg_ne (t : Fin (d + 1)) (j : Fin d) : reg t j ≠ t := by simp [reg, Fin.succ_ne_zero] theorem reg_injective (t : Fin (d + 1)) : Function.Injective (reg t) := by @@ -74,7 +74,7 @@ theorem reg_injective (t : Fin (d + 1)) : Function.Injective (reg t) := by simpa [reg] using h /-- The children's registers are exactly the registers other than the target. -/ -theorem mem_map_reg_finRange {t r : Fin (d + 1)} : +private theorem mem_map_reg_finRange {t r : Fin (d + 1)} : r ∈ (List.finRange d).map (reg t) ↔ r ≠ t := by refine ⟨?_, fun hr => ?_⟩ · simp only [List.mem_map, List.mem_finRange, true_and] @@ -126,7 +126,7 @@ noncomputable def proc (us : List Kˣ) : omit [Field K] in /-- Updating each child register in turn, as a function of its previous content, updates all registers other than the target. -/ -theorem foldl_update_reg (t : Fin (d + 1)) (g : Fin (d + 1) → (Fin ℓ → K) → Fin ℓ → K) +private theorem foldl_update_reg (t : Fin (d + 1)) (g : Fin (d + 1) → (Fin ℓ → K) → Fin ℓ → K) (l : List (Fin d)) (hl : l.Nodup) (S : State K d ℓ) : l.foldl (fun S j => Function.update S (reg t j) (g (reg t j) (S (reg t j)))) S = fun r => if r ∈ l.map (reg t) then g r (S r) else S r := by @@ -147,7 +147,7 @@ theorem foldl_update_reg (t : Fin (d + 1)) (g : Fin (d + 1) → (Fin ℓ → K) /-- A round, when all subtree procedures meet their specification, changes only the target register, subtracting `c` times the gate's extension at the masked children's values. -/ -theorem gateRound_eq {p : Fin d → K → Fin (d + 1) → State K d ℓ → State K d ℓ} +private theorem gateRound_eq {p : Fin d → K → Fin (d + 1) → State K d ℓ → State K d ℓ} {v : Fin d → Fin ℓ → K} (hp : ∀ j c t S, p j c t S = Function.update S t (S t + c • v j)) (f : Gate d ℓ) (c : K) (t : Fin (d + 1)) (u : Kˣ) (S : State K d ℓ) : gateRound p f c t u S = Function.update S t fun i => @@ -184,7 +184,7 @@ theorem gateRound_eq {p : Fin d → K → Fin (d + 1) → State K d ℓ → Stat /-- The rounds for all units in `us` change only the target register, subtracting `c` times the sum of the gate's extension at the masked children's values. -/ -theorem foldl_gateRound_eq {p : Fin d → K → Fin (d + 1) → State K d ℓ → State K d ℓ} +private theorem foldl_gateRound_eq {p : Fin d → K → Fin (d + 1) → State K d ℓ → State K d ℓ} {v : Fin d → Fin ℓ → K} (hp : ∀ j c t S, p j c t S = Function.update S t (S t + c • v j)) (f : Gate d ℓ) (c : K) (t : Fin (d + 1)) (us : List Kˣ) (S : State K d ℓ) : us.foldl (fun S u => gateRound p f c t u S) S = Function.update S t fun i => diff --git a/Complexity/Computability/TreeEval/CookMertz.lean b/Complexity/Computability/TreeEval/CookMertz.lean index 01049cb59..9447787fa 100644 --- a/Complexity/Computability/TreeEval/CookMertz.lean +++ b/Complexity/Computability/TreeEval/CookMertz.lean @@ -104,7 +104,7 @@ private theorem add_two_ne_add_one (t : Fin 3) : t + 2 ≠ t + 1 := by revert t; /-- A round, when both subtree procedures meet their specification, changes only the target register, subtracting `c` times the gate's extension at the masked children's values. -/ -theorem gateRound_eq {pl pr : K → Fin 3 → State K ℓ → State K ℓ} {vl vr : Fin ℓ → K} +private theorem gateRound_eq {pl pr : K → Fin 3 → State K ℓ → State K ℓ} {vl vr : Fin ℓ → K} (hl : ∀ c t S, pl c t S = Function.update S t (S t + c • vl)) (hr : ∀ c t S, pr c t S = Function.update S t (S t + c • vr)) (f : Gate ℓ) (c : K) (t : Fin 3) (u : Kˣ) @@ -130,7 +130,7 @@ theorem gateRound_eq {pl pr : K → Fin 3 → State K ℓ → State K ℓ} {vl v /-- The rounds for all units in `us` change only the target register, subtracting `c` times the sum of the gate's extension at the masked children's values. -/ -theorem foldl_gateRound_eq {pl pr : K → Fin 3 → State K ℓ → State K ℓ} {vl vr : Fin ℓ → K} +private theorem foldl_gateRound_eq {pl pr : K → Fin 3 → State K ℓ → State K ℓ} {vl vr : Fin ℓ → K} (hl : ∀ c t S, pl c t S = Function.update S t (S t + c • vl)) (hr : ∀ c t S, pr c t S = Function.update S t (S t + c • vr)) (f : Gate ℓ) (c : K) (t : Fin 3) (us : List Kˣ) diff --git a/Complexity/Computability/TreeEval/Encoding.lean b/Complexity/Computability/TreeEval/Encoding.lean index 0adaa26b6..734cd6949 100644 --- a/Complexity/Computability/TreeEval/Encoding.lean +++ b/Complexity/Computability/TreeEval/Encoding.lean @@ -71,13 +71,13 @@ def bodyLength (ℓ : ℕ) : ℕ → ℕ | d + 1 => tableLength ℓ + 2 * bodyLength ℓ d /-- A gate table on `ℓ ≥ 1` bits has at least `2 ^ ℓ` bits. -/ -theorem two_pow_le_tableLength {ℓ : ℕ} (hℓ : 1 ≤ ℓ) : 2 ^ ℓ ≤ tableLength ℓ := +private theorem two_pow_le_tableLength {ℓ : ℕ} (hℓ : 1 ≤ ℓ) : 2 ^ ℓ ≤ tableLength ℓ := calc 2 ^ ℓ ≤ 4 ^ ℓ := Nat.pow_le_pow_left (by decide) ℓ _ = 4 ^ ℓ * 1 := (Nat.mul_one _).symm _ ≤ 4 ^ ℓ * ℓ := Nat.mul_le_mul_left _ hℓ /-- The body of a height-`H` tree has at least `2 ^ H * ℓ` bits from its leaves alone. -/ -theorem two_pow_mul_le_bodyLength (ℓ H : ℕ) : 2 ^ H * ℓ ≤ bodyLength ℓ H := by +private theorem two_pow_mul_le_bodyLength (ℓ H : ℕ) : 2 ^ H * ℓ ≤ bodyLength ℓ H := by induction H with | zero => simp [bodyLength] | succ d ih => simp only [bodyLength, Nat.pow_succ', Nat.mul_assoc]; omega diff --git a/Complexity/Computability/TreeEval/Reader/Arith.lean b/Complexity/Computability/TreeEval/Reader/Arith.lean index 2a3fb1a73..d783ba8d4 100644 --- a/Complexity/Computability/TreeEval/Reader/Arith.lean +++ b/Complexity/Computability/TreeEval/Reader/Arith.lean @@ -66,8 +66,8 @@ section Cast ((chi p b x : ℕ) : ZMod p) = if b then (x : ZMod p) else 1 - x := by cases b <;> simp [chi, sub_eq_add_neg] -theorem mulMod_lt (hp : 0 < p) (a b : ℕ) : mulMod p a b < p := Nat.mod_lt _ hp -theorem addMod_lt (hp : 0 < p) (a b : ℕ) : addMod p a b < p := Nat.mod_lt _ hp +private theorem mulMod_lt (hp : 0 < p) (a b : ℕ) : mulMod p a b < p := Nat.mod_lt _ hp +private theorem addMod_lt (hp : 0 < p) (a b : ℕ) : addMod p a b < p := Nat.mod_lt _ hp variable [Fact p.Prime] @@ -78,7 +78,7 @@ variable [Fact p.Prime] simp [sgnVal, Iter.sgn, Nat.cast_sub this.le] /-- Fermat: a nonzero residue to the power `p - 2` is its inverse. -/ -theorem pow_sub_two_eq_inv {a : ZMod p} (ha : a ≠ 0) : a ^ (p - 2) = a⁻¹ := by +private theorem pow_sub_two_eq_inv {a : ZMod p} (ha : a ≠ 0) : a ^ (p - 2) = a⁻¹ := by have hp := (Fact.out : p.Prime).two_le refine eq_inv_of_mul_eq_one_left ?_ rw [← pow_succ, show p - 2 + 1 = p - 1 by omega, ZMod.pow_card_sub_one_eq_one ha] @@ -107,11 +107,11 @@ def Regs.WF (p ℓ : ℕ) (R : Regs) : Prop := @[simp] theorem Regs.get_set_self (R : Regs) (r : Fin 3) (l : List ℕ) : (R.set r l).get r = l := by fin_cases r <;> rfl -theorem Regs.get_set_of_ne (R : Regs) {r r' : Fin 3} (h : r' ≠ r) (l : List ℕ) : +private theorem Regs.get_set_of_ne (R : Regs) {r r' : Fin 3} (h : r' ≠ r) (l : List ℕ) : (R.set r l).get r' = R.get r' := by fin_cases r <;> fin_cases r' <;> first | rfl | exact absurd rfl h -theorem Regs.get_set (R : Regs) (r r' : Fin 3) (l : List ℕ) : +private theorem Regs.get_set (R : Regs) (r r' : Fin 3) (l : List ℕ) : (R.set r l).get r' = if r' = r then l else R.get r' := by split_ifs with h · subst h; exact R.get_set_self _ _ @@ -120,7 +120,7 @@ theorem Regs.get_set (R : Regs) (r r' : Fin 3) (l : List ℕ) : variable {ℓ : ℕ} omit [Fact p.Prime] in -theorem Regs.WF.set {R : Regs} (hR : R.WF p ℓ) {t : Fin 3} {l : List ℕ} (hl : l.length = ℓ) +private theorem Regs.WF.set {R : Regs} (hR : R.WF p ℓ) {t : Fin 3} {l : List ℕ} (hl : l.length = ℓ) (hv : ∀ v ∈ l, v < p) : (R.set t l).WF p ℓ := by intro r rw [Regs.get_set] @@ -196,7 +196,7 @@ theorem toState_subtractSums (R : Regs) (c : ℕ) (t : Fin 3) (acc : List ℕ) /-! ### Weights and the multilinear extension -/ -theorem cast_foldl_mulMod (F : ℕ → ℕ) (n : ℕ) : +private theorem cast_foldl_mulMod (F : ℕ → ℕ) (n : ℕ) : (((List.range n).foldl (fun a j => mulMod p a (F j)) (1 % p) : ℕ) : ZMod p) = ∏ j ∈ Finset.range n, (F j : ZMod p) := by induction n with @@ -243,7 +243,7 @@ omit [Fact p.Prime] in theorem four_pow_eq (ℓ : ℕ) : 4 ^ ℓ = 2 ^ (ℓ + ℓ) := by rw [← two_mul, pow_mul]; norm_num /-- The indices `k < 4^ℓ`, read as the low and high bits, enumerate the inputs of a gate. -/ -theorem sum_cube {M : Type*} [AddCommMonoid M] (G : (Fin ℓ ⊕ Fin ℓ → Bool) → M) : +private theorem sum_cube {M : Type*} [AddCommMonoid M] (G : (Fin ℓ ⊕ Fin ℓ → Bool) → M) : ∑ a, G a = ∑ k ∈ Finset.range (4 ^ ℓ), G (Sum.elim (lowBits ℓ k) (highBits ℓ k)) := by rw [← (cubeEquiv ℓ).symm.sum_comp, four_pow_eq, ← Fin.sum_univ_eq_sum_range (fun k => G (Sum.elim (lowBits ℓ k) (highBits ℓ k)))] diff --git a/Complexity/Computability/TreeEval/Reader/Cert/Machine.lean b/Complexity/Computability/TreeEval/Reader/Cert/Machine.lean index b2e7eeefe..df67a050e 100644 --- a/Complexity/Computability/TreeEval/Reader/Cert/Machine.lean +++ b/Complexity/Computability/TreeEval/Reader/Cert/Machine.lean @@ -41,19 +41,19 @@ theorem pairFalse_inSpace : ReadMachine.pairFalse_inSpace fun x => by simp only [stepBudget, encStepInT]; omega /-- A function of the tuple with the bit `false` within the budget of the step. -/ -theorem onTuple {β : Type} {encB : β ↪ List Bool} {f : Tuple × Bool → β} +private theorem onTuple {β : Type} {encB : β ↪ List Bool} {f : Tuple × Bool → β} (h : ComputableTidilyInSpace f encStepInT encB stepBudget) : ComputableTidilyInSpace (fun x : Tuple => f (x, false)) encTuple encB fun x => stepBudget (x, false) := ReadMachine.comp_pairFalse_inSpace (fun x => by simp only [stepBudget, encStepInT]; omega) h /-- **The halting test** on tuples. -/ -theorem haltT_inSpace : +private theorem haltT_inSpace : ComputableTidilyInSpace haltT encTuple encBool fun x => stepBudget (x, false) := onTuple (budget_finite (encC := encBool) (fun t : Fin 7 => decide (t = 6)) hTag) /-- The offset of the node at the path of a stack. -/ -theorem offsetT_inSpace {st : Tuple × Bool → List Frame} +private theorem offsetT_inSpace {st : Tuple × Bool → List Frame} (hst : ComputableTidilyInSpace st encStepInT (encList encFrame) stepBudget) : ComputableTidilyInSpace (fun y => offsetT y.1 (st y)) encStepInT encNat stepBudget := by have hdirs := budget_comp dirs_inSpace hst (.const_mul 64 ((length_le hst).add (.const 1 _))) @@ -65,7 +65,7 @@ theorem offsetT_inSpace {st : Tuple × Bool → List Frame} simp only [offsetT, path_eq_reverse, foldl_cons_dir, List.append_nil] /-- **The address** on tuples. -/ -theorem addrT_inSpace : +private theorem addrT_inSpace : ComputableTidilyInSpace addrT encTuple (encOption encNat) fun x => stepBudget (x, false) := by have hsome {n : Tuple × Bool → ℕ} (hn : ComputableTidilyInSpace n encStepInT encNat stepBudget) : ComputableTidilyInSpace (fun y => some (n y)) encStepInT (encOption encNat) stepBudget := @@ -87,19 +87,20 @@ theorem addrT_inSpace : /-- **The space budget of a state.** -/ noncomputable def stateBudget (s : State) : ℕ := stepBudget (s.toTuple, false) -theorem stepBudget_bool (x : Tuple) (b : Bool) : stepBudget (x, b) = stepBudget (x, false) := by +private theorem stepBudget_bool (x : Tuple) (b : Bool) : stepBudget (x, b) = stepBudget + (x, false) := by simp [stepBudget, encBool_apply] -theorem halt_inSpace : ComputableTidilyInSpace machine.halt encState encBool stateBudget := +private theorem halt_inSpace : ComputableTidilyInSpace machine.halt encState encBool stateBudget := (haltT_inSpace.of_encIn_eq State.toTuple fun _ => rfl).of_enc_eq fun s => by rw [haltT_toTuple] -theorem addr_inSpace : ComputableTidilyInSpace machine.addr encState (encOption encNat) +private theorem addr_inSpace : ComputableTidilyInSpace machine.addr encState (encOption encNat) stateBudget := (addrT_inSpace.of_encIn_eq State.toTuple fun _ => rfl).of_enc_eq fun s => by rw [addrT_toTuple]; rfl -theorem step_inSpace : +private theorem step_inSpace : ComputableTidilyInSpace (fun p : State × Bool => machine.step p.1 p.2) (encPair encState encBool) (encPair encState encBits) fun p => stateBudget p.1 := by have h := stepT_inSpace.of_encIn_eq (fun p : State × Bool => (p.1.toTuple, p.2)) fun p => by diff --git a/Complexity/Computability/TreeEval/Reader/Cert/Offset.lean b/Complexity/Computability/TreeEval/Reader/Cert/Offset.lean index 812844c6c..a41344ecc 100644 --- a/Complexity/Computability/TreeEval/Reader/Cert/Offset.lean +++ b/Complexity/Computability/TreeEval/Reader/Cert/Offset.lean @@ -32,7 +32,7 @@ namespace Reader open Turing MultiTapeTM ComputableTidilyInSpace Iter -theorem bodyLength_add_tableLength_le (ℓ d : ℕ) : +private theorem bodyLength_add_tableLength_le (ℓ d : ℕ) : bodyLength ℓ d + tableLength ℓ ≤ 2 ^ d * (ℓ + tableLength ℓ) := by induction d with | zero => simp [bodyLength] @@ -70,7 +70,7 @@ theorem foldl_cons_dir (st : List Frame) (acc : List Bool) : | nil => rfl | cons fr st ih => simp [ih] -theorem pathOffset_le_bodyLength (ℓ : ℕ) (P : List Bool) : +private theorem pathOffset_le_bodyLength (ℓ : ℕ) (P : List Bool) : ∀ d, pathOffset ℓ d P ≤ bodyLength ℓ d := by induction P with | nil => intro d; simp [pathOffset] @@ -85,7 +85,7 @@ theorem pathOffset_le_bodyLength (ℓ : ℕ) (P : List Bool) : /-! ### Certificates -/ -theorem length_encNat_pow_four (k : ℕ) : (encNat (4 ^ k)).length ≤ 2 * k + 1 := by +private theorem length_encNat_pow_four (k : ℕ) : (encNat (4 ^ k)).length ≤ 2 * k + 1 := by have h : 4 ^ k = 2 ^ (2 * k) := by rw [pow_mul]; norm_num rw [length_encNat_eq_size] refine Nat.size_le.mpr ?_ @@ -98,7 +98,7 @@ theorem length_tableLength_le (ℓ : ℕ) : (encNat (tableLength ℓ)).length have h₃ := length_encNat_le_self ℓ rw [tableLength]; omega -theorem iterate_mul_four (k : ℕ) : (fun x => x * 4)^[k] 1 = 4 ^ k := by +private theorem iterate_mul_four (k : ℕ) : (fun x => x * 4)^[k] 1 = 4 ^ k := by induction k with | zero => rfl | succ k ih => rw [Function.iterate_succ_apply', ih, pow_succ] @@ -124,11 +124,12 @@ theorem tableLength_inSpace : (hid.weaken hl'))).of_enc_eq fun ℓ => by rw [iterate_mul_four]; rfl have := length_encNat_le_self ℓ; omega -theorem length_encNat_two_pow (k : ℕ) : (encNat (2 ^ k)).length ≤ k + 1 := by +private theorem length_encNat_two_pow (k : ℕ) : (encNat (2 ^ k)).length ≤ k + 1 := by rw [length_encNat_eq_size] exact Nat.size_le.mpr (Nat.pow_lt_pow_right (by norm_num) (by omega)) -theorem length_bodyLength_le (ℓ k : ℕ) : (encNat (bodyLength ℓ k)).length ≤ k + 4 * ℓ + 4 := by +private theorem length_bodyLength_le (ℓ k : ℕ) : + (encNat (bodyLength ℓ k)).length ≤ k + 4 * ℓ + 4 := by have h₁ := ComputableTidilyInO.length_encNat_mono ((Nat.le_add_right _ _).trans (bodyLength_add_tableLength_le ℓ k)) have h₂ := length_encNat_mul_le (2 ^ k) (ℓ + tableLength ℓ) @@ -139,16 +140,16 @@ theorem length_bodyLength_le (ℓ k : ℕ) : (encNat (bodyLength ℓ k)).length omega /-- A step of the lengths of bodies, on `(G, b)`. -/ -def bodyStep (q : ℕ × ℕ) : ℕ × ℕ := (q.1, q.1 + 2 * q.2) +private def bodyStep (q : ℕ × ℕ) : ℕ × ℕ := (q.1, q.1 + 2 * q.2) -theorem iterate_bodyStep (ℓ k : ℕ) : +private theorem iterate_bodyStep (ℓ k : ℕ) : bodyStep^[k] (tableLength ℓ, ℓ) = (tableLength ℓ, bodyLength ℓ k) := by induction k with | zero => rfl | succ k ih => rw [Function.iterate_succ_apply', ih]; rfl /-- **The length of the body of a subtree**, `bodyLength ℓ e` from `(ℓ, e)`. -/ -theorem bodyLength_inSpace : +private theorem bodyLength_inSpace : ComputableTidilyInSpace (fun q : ℕ × ℕ => bodyLength q.1 q.2) (encPair encNat encNat) encNat fun q => 65536 * (q.1 + q.2 + 1) := by have hl : (fun q => (encPair encNat encNat q).length) ≼ fun q => 4096 * (q.1 + q.2 + 1) := @@ -206,7 +207,8 @@ theorem round_inSpace : /-! ### The offset of the node at the path of a stack -/ -theorem three_mul_length_le (st : List Frame) : 3 * st.length ≤ (encList encFrame st).length := by +private theorem three_mul_length_le (st : List Frame) : 3 * st.length ≤ + (encList encFrame st).length := by induction st with | nil => simp | cons fr st ih => @@ -215,7 +217,8 @@ theorem three_mul_length_le (st : List Frame) : 3 * st.length ≤ (encList encFr simp only [List.length_cons, List.map_cons, List.sum_cons] omega -theorem length_encList_bools (l : List Bool) : (encList encBool l).length = 3 * l.length := by +private theorem length_encList_bools (l : List Bool) : + (encList encBool l).length = 3 * l.length := by induction l with | nil => rfl | cons b l ih => rw [length_encList] at ih ⊢; simp; ring @@ -259,15 +262,15 @@ theorem dirs_inSpace : exact h.mono_le fun st => by omega /-- A step of the offset along a path, with the value length in the state. -/ -def pathStep' (q : ℕ × ℕ × ℕ) (b : Bool) : ℕ × ℕ × ℕ := (q.1, pathStep q.1 q.2 b) +private def pathStep' (q : ℕ × ℕ × ℕ) (b : Bool) : ℕ × ℕ × ℕ := (q.1, pathStep q.1 q.2 b) -theorem foldl_pathStep' (ℓ : ℕ) (P : List Bool) (s : ℕ × ℕ) : +private theorem foldl_pathStep' (ℓ : ℕ) (P : List Bool) (s : ℕ × ℕ) : P.foldl pathStep' (ℓ, s) = (ℓ, P.foldl (pathStep ℓ) s) := by induction P generalizing s with | nil => rfl | cons b P ih => rw [List.foldl_cons, List.foldl_cons, pathStep', ih] -theorem pathStep'_inSpace : +private theorem pathStep'_inSpace : ComputableTidilyInSpace (fun q : (ℕ × ℕ × ℕ) × Bool => pathStep' q.1 q.2) (encPair encNat3 encBool) encNat3 fun q => 2 ^ 20 * (q.1.1 + q.1.2.1 + (encPair encNat3 encBool q).length + 1) := by @@ -291,7 +294,7 @@ theorem pathStep'_inSpace : simp only [pathStep', pathStep] by_cases h : q.1.2.1 = 0 <;> simp [h] -theorem length_pathOffset_le (ℓ d : ℕ) (P : List Bool) : +private theorem length_pathOffset_le (ℓ d : ℕ) (P : List Bool) : (encNat (pathOffset ℓ d P)).length ≤ d + 4 * ℓ + 4 := (ComputableTidilyInO.length_encNat_mono (pathOffset_le_bodyLength ℓ P d)).trans (length_bodyLength_le ℓ d) diff --git a/Complexity/Computability/TreeEval/Reader/Cert/Regs.lean b/Complexity/Computability/TreeEval/Reader/Cert/Regs.lean index 41dd75dfe..bf4e66944 100644 --- a/Complexity/Computability/TreeEval/Reader/Cert/Regs.lean +++ b/Complexity/Computability/TreeEval/Reader/Cert/Regs.lean @@ -69,12 +69,12 @@ theorem set_inSpace {R : α → Regs} {t : α → Fin 3} {l : α → List ℕ} generalize t x = r fin_cases r <;> rfl -theorem length_mulMod_le (p a v : ℕ) : +private theorem length_mulMod_le (p a v : ℕ) : (encNat (mulMod p a v)).length ≤ (encNat p).length + (encNat a).length + (encNat v).length := (ComputableTidilyInO.length_encNat_mono (Nat.mod_le _ _)).trans ((length_encNat_mul_le a v).trans (by omega)) -theorem length_encList_map_mulMod_le (p a : ℕ) (l : List ℕ) : +private theorem length_encList_map_mulMod_le (p a : ℕ) (l : List ℕ) : (encList encNat (l.map (mulMod p a))).length ≤ (encList encNat l).length + l.length * (2 * ((encNat p).length + (encNat a).length)) := by induction l with @@ -153,11 +153,11 @@ theorem modifyAt_inSpace {l : α → List ℕ} {i p c : α → ℕ} nlinarith /-- A step of subtracting `c` times the sums `acc` from a register, on `((p, c, acc), i, out)`. -/ -def subStep (s : (ℕ × ℕ × List ℕ) × ℕ × List ℕ) (v : ℕ) : (ℕ × ℕ × List ℕ) × ℕ × List ℕ := +private def subStep (s : (ℕ × ℕ × List ℕ) × ℕ × List ℕ) (v : ℕ) : (ℕ × ℕ × List ℕ) × ℕ × List ℕ := (s.1, s.2.1 + 1, s.2.2 ++ [addMod s.1.1 v (negMod s.1.1 (mulMod s.1.1 s.1.2.1 (s.1.2.2.getD s.2.1 0)))]) -theorem foldl_subStep (p c : ℕ) (acc l : List ℕ) (j : ℕ) (out : List ℕ) : +private theorem foldl_subStep (p c : ℕ) (acc l : List ℕ) (j : ℕ) (out : List ℕ) : l.foldl subStep ((p, c, acc), j, out) = ((p, c, acc), j + l.length, out ++ l.mapIdx fun i v => addMod p v (negMod p (mulMod p c (acc.getD (j + i) 0)))) := by induction l generalizing j out with @@ -171,7 +171,7 @@ theorem foldl_subStep (p c : ℕ) (acc l : List ℕ) (j : ℕ) (out : List ℕ) Prod.mk.injEq, true_and, and_true] omega -theorem subtractSums_eq (p c : ℕ) (t : Fin 3) (acc : List ℕ) (R : Regs) : +private theorem subtractSums_eq (p c : ℕ) (t : Fin 3) (acc : List ℕ) (R : Regs) : subtractSums p c t acc R = R.set t (((R.get t).foldl subStep ((p, c, acc), 0, [])).2.2) := by rw [foldl_subStep, subtractSums] congr 1 @@ -180,13 +180,14 @@ theorem subtractSums_eq (p c : ℕ) (t : Fin 3) (acc : List ℕ) (R : Regs) : simp [List.getElem_mapIdx, List.getD_eq_getElem?_getD, hi] /-- The encoding of the parameters `(p, c, acc)` of `subStep`. -/ -abbrev encSubPar : ℕ × ℕ × List ℕ ↪ List Bool := encPair encNat (encPair encNat (encList encNat)) +private abbrev encSubPar : ℕ × ℕ × List ℕ ↪ List Bool := encPair encNat + (encPair encNat (encList encNat)) /-- The encoding of the states of `subStep`. -/ -abbrev encSubState : (ℕ × ℕ × List ℕ) × ℕ × List ℕ ↪ List Bool := +private abbrev encSubState : (ℕ × ℕ × List ℕ) × ℕ × List ℕ ↪ List Bool := encPair encSubPar (encPair encNat (encList encNat)) -theorem length_subElem_le (p c v a : ℕ) : +private theorem length_subElem_le (p c v a : ℕ) : (encNat (addMod p v (negMod p (mulMod p c a)))).length ≤ (encNat p).length + (encNat v).length := by rcases Nat.eq_zero_or_pos p with rfl | hp @@ -194,7 +195,7 @@ theorem length_subElem_le (p c v a : ℕ) : · have := ComputableTidilyInO.length_encNat_mono (Nat.mod_lt (v + negMod p (mulMod p c a)) hp).le simp only [addMod]; omega -theorem subStep_inSpace : +private theorem subStep_inSpace : ComputableTidilyInSpace (fun q : ((ℕ × ℕ × List ℕ) × ℕ × List ℕ) × ℕ => subStep q.1 q.2) (encPair encSubState encNat) encSubState fun q => 64 * ((encPair encSubState encNat q).length + 1) := by @@ -220,7 +221,7 @@ theorem subStep_inSpace : have hsucc := budget_comp_lin natSucc linear_succ hj exact budget_prod hpar (budget_prod hsucc happ) -theorem length_encList_mapIdx_le (l : List ℕ) (f : ℕ → ℕ → ℕ) (P : ℕ) +private theorem length_encList_mapIdx_le (l : List ℕ) (f : ℕ → ℕ → ℕ) (P : ℕ) (hf : ∀ i v, (encNat (f i v)).length ≤ P + (encNat v).length) : (encList encNat (l.mapIdx f)).length ≤ (encList encNat l).length + l.length * (2 * P) := by induction l generalizing f with @@ -233,7 +234,7 @@ theorem length_encList_mapIdx_le (l : List ℕ) (f : ℕ → ℕ → ℕ) (P : nlinarith /-- **The register with `c` times the sums subtracted**, from `((p, c, acc), r)`. -/ -theorem subtractList_inSpace : +private theorem subtractList_inSpace : ComputableTidilyInSpace (fun q : (ℕ × ℕ × List ℕ) × List ℕ => (q.2.foldl subStep (q.1, 0, [])).2.2) (encPair encSubPar (encList encNat)) (encList encNat) diff --git a/Complexity/Computability/TreeEval/Reader/Cert/Residue.lean b/Complexity/Computability/TreeEval/Reader/Cert/Residue.lean index ae6d6b1f4..524a3056b 100644 --- a/Complexity/Computability/TreeEval/Reader/Cert/Residue.lean +++ b/Complexity/Computability/TreeEval/Reader/Cert/Residue.lean @@ -31,7 +31,7 @@ namespace Reader open Turing MultiTapeTM ComputableTidilyInSpace /-- The projections of a triple. -/ -theorem proj3 : +private theorem proj3 : ComputableTidilyInSpace (fun q : ℕ × ℕ × ℕ => q.1) encNat3 encNat (fun q => (encNat3 q).length) ∧ ComputableTidilyInSpace (fun q : ℕ × ℕ × ℕ => q.2.1) encNat3 encNat @@ -79,9 +79,9 @@ theorem chi_inSpace : exact (budget_ite (snd _ _) hmod hadd).of_enc_eq fun q => by simp only [chi] /-- One factor of a power modulo `p`, on `(p, a, acc)`. -/ -def powStep (q : ℕ × ℕ × ℕ) : ℕ × ℕ × ℕ := (q.1, q.2.1, mulMod q.1 q.2.2 q.2.1) +private def powStep (q : ℕ × ℕ × ℕ) : ℕ × ℕ × ℕ := (q.1, q.2.1, mulMod q.1 q.2.2 q.2.1) -theorem iterate_powStep (p a n : ℕ) : powStep^[n] (p, a, 1 % p) = (p, a, powMod p a n) := by +private theorem iterate_powStep (p a n : ℕ) : powStep^[n] (p, a, 1 % p) = (p, a, powMod p a n) := by induction n with | zero => rfl | succ n ih => rw [Function.iterate_succ_apply', ih]; rfl diff --git a/Complexity/Computability/TreeEval/Reader/Cert/Step.lean b/Complexity/Computability/TreeEval/Reader/Cert/Step.lean index 4bea27e1d..ef844d42f 100644 --- a/Complexity/Computability/TreeEval/Reader/Cert/Step.lean +++ b/Complexity/Computability/TreeEval/Reader/Cert/Step.lean @@ -63,7 +63,8 @@ theorem height_le_stepBudget : (fun y : Tuple × Bool => y.1.height) ≼ stepBud /-- The product of the length of the registers and of a length bounded by the prime, the round of the top frame and the value length is within the budget. -/ -theorem mul_le_stepBudget {u v : Tuple × Bool → ℕ} (hu : ∀ y, u y ≤ regLen y.1 + y.1.ell + 1) +private theorem mul_le_stepBudget {u v : Tuple × Bool → ℕ} + (hu : ∀ y, u y ≤ regLen y.1 + y.1.ell + 1) (hv : ∀ y, v y ≤ 2 * ((encNat y.1.p).length + (encNat (y.1.stack.headD dfr).round).length + (encNat y.1.ell).length + 4)) : (fun y => u y * v y) ≼ stepBudget := by @@ -72,25 +73,26 @@ theorem mul_le_stepBudget {u v : Tuple × Bool → ℕ} (hu : ∀ y, u y ≤ reg simp only [stepBudget] nlinarith -theorem length_get_le_regLen (x : Tuple) (r : Fin 3) : (x.regs.get r).length ≤ regLen x := by +private theorem length_get_le_regLen (x : Tuple) (r : Fin 3) : + (x.regs.get r).length ≤ regLen x := by fin_cases r <;> simp [Regs.get, regLen] <;> omega /-! ### Projections -/ section Proj -theorem projT_inSpace {β : Type} {encB : β ↪ List Bool} {f : Tuple × Bool → β} +private theorem projT_inSpace {β : Type} {encB : β ↪ List Bool} {f : Tuple × Bool → β} (h : ComputableTidilyInSpace f encStepInT encB fun y => (encStepInT y).length) : ComputableTidilyInSpace f encStepInT encB stepBudget := h.weaken len_le_stepBudget -theorem hTup : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1) encStepInT encTuple +private theorem hTup : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1) encStepInT encTuple stepBudget := projT_inSpace (fst _ _) -theorem hBit : ComputableTidilyInSpace (fun y : Tuple × Bool => y.2) encStepInT encBool +private theorem hBit : ComputableTidilyInSpace (fun y : Tuple × Bool => y.2) encStepInT encBool stepBudget := projT_inSpace (snd _ _) -theorem hParams : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.1.1) encStepInT +private theorem hParams : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.1.1) encStepInT (encPair encNat (encPair encNat encNat)) stepBudget := fst' (fst' hTup) theorem hEll : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.ell) encStepInT encNat @@ -99,22 +101,25 @@ theorem hEll : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.ell) encSte theorem hHeight : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.height) encStepInT encNat stepBudget := fst' (snd' hParams) -theorem hP : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.p) encStepInT encNat +private theorem hP : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.p) encStepInT encNat stepBudget := snd' (snd' hParams) -theorem hRegs : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.regs) encStepInT encRegs +private theorem hRegs : ComputableTidilyInSpace + (fun y : Tuple × Bool => y.1.regs) encStepInT encRegs stepBudget := snd' (fst' hTup) -theorem hStackMode : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.2.1) encStepInT +private theorem hStackMode : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.2.1) encStepInT (encPair (encList encFrame) encMode) stepBudget := fst' (snd' hTup) theorem hStack : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.stack) encStepInT (encList encFrame) stepBudget := fst' hStackMode -theorem hMode : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.mode) encStepInT encMode +private theorem hMode : ComputableTidilyInSpace + (fun y : Tuple × Bool => y.1.mode) encStepInT encMode stepBudget := snd' hStackMode -theorem hCtl : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.2.2) encStepInT encCtlTuple +private theorem hCtl : ComputableTidilyInSpace + (fun y : Tuple × Bool => y.1.2.2) encStepInT encCtlTuple stepBudget := snd' (snd' hTup) theorem hTag : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.tag) encStepInT @@ -123,14 +128,15 @@ theorem hTag : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.tag) encSte theorem hN₁ : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.n₁) encStepInT encNat stepBudget := fst' (snd' hCtl) -theorem hN₂ : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.n₂) encStepInT encNat +private theorem hN₂ : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.n₂) encStepInT encNat stepBudget := fst' (snd' (snd' hCtl)) -theorem hAcc : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.acc) encStepInT +private theorem hAcc : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.acc) encStepInT (encList encNat) stepBudget := snd' (snd' (snd' hCtl)) /-- The top frame. -/ -theorem hTop : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.stack.headD dfr) encStepInT +private theorem hTop : ComputableTidilyInSpace + (fun y : Tuple × Bool => y.1.stack.headD dfr) encStepInT encFrame stepBudget := budget_comp_linear (of_inO (.of_linear (ListEncoding.headD (enc := encList encFrame) dfr))) hStack @@ -141,18 +147,19 @@ theorem hRest : ComputableTidilyInSpace (fun y : Tuple × Bool => y.1.stack.tail budget_comp_linear (of_inO (.of_linear (ListEncoding.tail encFrame))) hStack /-- A function of the finite fields of the top frame. -/ -theorem hTopFinite {β : Type} {encB : β ↪ List Bool} (g : Fin 4 × Bool × Fin 3 → β) : +private theorem hTopFinite {β : Type} {encB : β ↪ List Bool} (g : Fin 4 × Bool × Fin 3 → β) : ComputableTidilyInSpace (fun y : Tuple × Bool => g (Frame.equiv (y.1.stack.headD dfr)).2) encStepInT encB stepBudget := budget_comp_linear (f := fun y : Tuple × Bool => y.1.stack.headD dfr) (frameFinite_inSpace g) hTop -theorem hRound : ComputableTidilyInSpace (fun y : Tuple × Bool => (y.1.stack.headD dfr).round) +private theorem hRound : ComputableTidilyInSpace + (fun y : Tuple × Bool => (y.1.stack.headD dfr).round) encStepInT encNat stepBudget := budget_comp_linear round_inSpace hTop /-- A function of the mode. -/ -theorem hModeFinite {β : Type} {encB : β ↪ List Bool} (g : Mode → β) : +private theorem hModeFinite {β : Type} {encB : β ↪ List Bool} (g : Mode → β) : ComputableTidilyInSpace (fun y : Tuple × Bool => g y.1.mode) encStepInT encB stepBudget := budget_finite g hMode @@ -164,19 +171,19 @@ section Build variable {β : Type} {encIn : β ↪ List Bool} {Bs : β → ℕ} -theorem mkFrame_inSpace {j : β → ℕ} {g : β → Fin 4 × Bool × Fin 3} +private theorem mkFrame_inSpace {j : β → ℕ} {g : β → Fin 4 × Bool × Fin 3} (hj : ComputableTidilyInSpace j encIn encNat Bs) (hg : ComputableTidilyInSpace g encIn (encFinite (Fin 4 × Bool × Fin 3)) Bs) : ComputableTidilyInSpace (fun x => Frame.equiv.symm (j x, g x)) encIn encFrame Bs := (budget_prod hj hg).of_enc_eq fun x => by rw [encFrame_apply, Equiv.apply_symm_apply] -theorem cons_inSpace {ε : Type} {enc : ε ↪ List Bool} {a : β → ε} {l : β → List ε} +private theorem cons_inSpace {ε : Type} {enc : ε ↪ List Bool} {a : β → ε} {l : β → List ε} (ha : ComputableTidilyInSpace a encIn enc Bs) (hl : ComputableTidilyInSpace l encIn (encList enc) Bs) : ComputableTidilyInSpace (fun x => a x :: l x) encIn (encList enc) Bs := budget_comp_linear (of_inO (ComputableTidilyInDegree.cons enc).inO_one) (budget_prod ha hl) -theorem mkTuple_inSpace {e h p : β → ℕ} {R : β → Regs} {st : β → List Frame} {m : β → Mode} +private theorem mkTuple_inSpace {e h p : β → ℕ} {R : β → Regs} {st : β → List Frame} {m : β → Mode} {c : β → Fin 7 × ℕ × ℕ × List ℕ} (he : ComputableTidilyInSpace e encIn encNat Bs) (hh : ComputableTidilyInSpace h encIn encNat Bs) @@ -190,7 +197,7 @@ theorem mkTuple_inSpace {e h p : β → ℕ} {R : β → Regs} {st : β → List budget_prod (budget_prod (budget_prod he (budget_prod hh hp)) hR) (budget_prod (budget_prod hst hm) hc) -theorem mkCtl_inSpace {t : β → Fin 7} {a b : β → ℕ} {acc : β → List ℕ} +private theorem mkCtl_inSpace {t : β → Fin 7} {a b : β → ℕ} {acc : β → List ℕ} (ht : ComputableTidilyInSpace t encIn (encFinite (Fin 7)) Bs) (ha : ComputableTidilyInSpace a encIn encNat Bs) (hb : ComputableTidilyInSpace b encIn encNat Bs) @@ -207,25 +214,25 @@ section Branches /-- The encoding of the results of a step. -/ noncomputable abbrev encStepOut : Tuple × List Bool ↪ List Bool := encPair encTuple encBits -theorem out_inSpace {T : Tuple × Bool → Tuple} +private theorem out_inSpace {T : Tuple × Bool → Tuple} (hT : ComputableTidilyInSpace T encStepInT encTuple stepBudget) : ComputableTidilyInSpace (fun y => (T y, ([] : List Bool))) encStepInT encStepOut stepBudget := budget_prod hT (budget_const [] len_le_stepBudget) -theorem withCtl_inSpace {c : Tuple × Bool → Fin 7 × ℕ × ℕ × List ℕ} +private theorem withCtl_inSpace {c : Tuple × Bool → Fin 7 × ℕ × ℕ × List ℕ} (hc : ComputableTidilyInSpace c encStepInT encCtlTuple stepBudget) : ComputableTidilyInSpace (fun y => y.1.withCtl (c y)) encStepInT encTuple stepBudget := budget_prod (fst' hTup) (budget_prod hStackMode hc) -theorem hConstTag (t : Fin 7) : +private theorem hConstTag (t : Fin 7) : ComputableTidilyInSpace (fun _ : Tuple × Bool => t) encStepInT (encFinite (Fin 7)) stepBudget := budget_const t len_le_stepBudget -theorem hConstNat (n : ℕ) : +private theorem hConstNat (n : ℕ) : ComputableTidilyInSpace (fun _ : Tuple × Bool => n) encStepInT encNat stepBudget := budget_const n len_le_stepBudget -theorem hNil : +private theorem hNil : ComputableTidilyInSpace (fun _ : Tuple × Bool => ([] : List ℕ)) encStepInT (encList encNat) stepBudget := budget_const [] len_le_stepBudget @@ -234,7 +241,7 @@ theorem hSucc {n : Tuple × Bool → ℕ} (hn : ComputableTidilyInSpace n encSte budget_comp_lin natSucc linear_succ hn /-- The header: reading the value length. -/ -theorem branch0_inSpace : +private theorem branch0_inSpace : ComputableTidilyInSpace (fun y : Tuple × Bool => if y.2 then (y.1.withCtl (0, y.1.n₁ + 1, 0, []), ([] : List Bool)) else ((((y.1.n₁, y.1.height, y.1.p), y.1.regs), y.1.2.1, (1, 0, 0, [])), [])) @@ -245,7 +252,7 @@ theorem branch0_inSpace : (budget_prod hStackMode (mkCtl_inSpace (hConstTag 1) (hConstNat 0) (hConstNat 0) hNil)))) /-- The header: reading the height. -/ -theorem branch1_inSpace : +private theorem branch1_inSpace : ComputableTidilyInSpace (fun y : Tuple × Bool => if y.2 then (y.1.withCtl (1, y.1.n₁ + 1, 0, []), ([] : List Bool)) else ((((y.1.ell, y.1.n₁, y.1.p), y.1.regs), y.1.2.1, (2, 2 * y.1.ell + 2, 2, [])), [])) @@ -259,7 +266,7 @@ theorem branch1_inSpace : (out_inSpace (budget_prod (budget_prod (budget_prod hEll (budget_prod hN₁ hP)) hRegs) (budget_prod hStackMode (mkCtl_inSpace (hConstTag 2) h2e (hConstNat 2) hNil)))) -theorem hReplicate : +private theorem hReplicate : ComputableTidilyInSpace (fun y : Tuple × Bool => List.replicate y.1.ell 0) encStepInT (encList encNat) stepBudget := by refine budget_comp replicate (budget_prod hEll (hConstNat 0)) (.const_mul 64 ?_) @@ -267,7 +274,7 @@ theorem hReplicate : simp only [length_encPair]; have : (encNat 0).length = 0 := rfl; omega /-- The search for the prime. -/ -theorem branch2_inSpace : +private theorem branch2_inSpace : ComputableTidilyInSpace (fun y : Tuple × Bool => if y.1.n₂ < y.1.n₁ then if y.1.n₁ % y.1.n₂ = 0 then (y.1.withCtl (2, y.1.n₁ + 1, 2, []), ([] : List Bool)) @@ -297,19 +304,20 @@ theorem branch2_inSpace : (out_inSpace hfound)).of_enc_eq fun y => ?_ simp only [decide_eq_true_eq] -theorem hLt {a b : Tuple × Bool → ℕ} (ha : ComputableTidilyInSpace a encStepInT encNat stepBudget) +private theorem hLt {a b : Tuple × Bool → ℕ} + (ha : ComputableTidilyInSpace a encStepInT encNat stepBudget) (hb : ComputableTidilyInSpace b encStepInT encNat stepBudget) : ComputableTidilyInSpace (fun y => decide (a y < b y)) encStepInT encBool stepBudget := budget_comp_lin natLt linear_succ (budget_prod ha hb) -theorem hSgnVal {p : Tuple × Bool → ℕ} {neg : Tuple × Bool → Bool} +private theorem hSgnVal {p : Tuple × Bool → ℕ} {neg : Tuple × Bool → Bool} (hp : ComputableTidilyInSpace p encStepInT encNat stepBudget) (hneg : ComputableTidilyInSpace neg encStepInT encBool stepBudget) : ComputableTidilyInSpace (fun y => sgnVal (p y) (neg y)) encStepInT encNat stepBudget := (budget_ite hneg (budget_comp_lin natPred linear_succ hp) (hConstNat 1)) |>.of_enc_eq fun y => by simp only [sgnVal] -theorem withRegsModeCtl_inSpace {R : Tuple × Bool → Regs} {st : Tuple × Bool → List Frame} +private theorem withRegsModeCtl_inSpace {R : Tuple × Bool → Regs} {st : Tuple × Bool → List Frame} {m : Tuple × Bool → Mode} {c : Tuple × Bool → Fin 7 × ℕ × ℕ × List ℕ} (hR : ComputableTidilyInSpace R encStepInT encRegs stepBudget) (hst : ComputableTidilyInSpace st encStepInT (encList encFrame) stepBudget) @@ -320,7 +328,7 @@ theorem withRegsModeCtl_inSpace {R : Tuple × Bool → Regs} {st : Tuple × Bool mkTuple_inSpace hEll hHeight hP hR hst hm hc /-- Reading a leaf. -/ -theorem branch4_inSpace : +private theorem branch4_inSpace : ComputableTidilyInSpace (fun y : Tuple × Bool => if y.1.mode.isCall then if y.1.n₁ < y.1.ell then @@ -345,28 +353,29 @@ theorem branch4_inSpace : (out_inSpace hTup)).of_enc_eq fun y => ?_ simp only [decide_eq_true_eq] -theorem hFrTarget : ComputableTidilyInSpace (fun y : Tuple × Bool => (y.1.stack.headD dfr).target) +private theorem hFrTarget : ComputableTidilyInSpace + (fun y : Tuple × Bool => (y.1.stack.headD dfr).target) encStepInT encReg stepBudget := hTopFinite (fun g => g.2.2) -theorem hFrNeg : ComputableTidilyInSpace (fun y : Tuple × Bool => (y.1.stack.headD dfr).neg) +private theorem hFrNeg : ComputableTidilyInSpace (fun y : Tuple × Bool => (y.1.stack.headD dfr).neg) encStepInT encBool stepBudget := hTopFinite (fun g => g.2.1) -theorem hRegPlus (k : Fin 3) : +private theorem hRegPlus (k : Fin 3) : ComputableTidilyInSpace (fun y : Tuple × Bool => (y.1.stack.headD dfr).target + k) encStepInT encReg stepBudget := hTopFinite (fun g => g.2.2 + k) /-- The top frame with a new phase. -/ -theorem hFrPhase (ph : Fin 4) : +private theorem hFrPhase (ph : Fin 4) : ComputableTidilyInSpace (fun y : Tuple × Bool => { y.1.stack.headD dfr with phase := ph }) encStepInT encFrame stepBudget := (mkFrame_inSpace hRound (hTopFinite (encB := encFinite (Fin 4 × Bool × Fin 3)) fun g => (ph, g.2.1, g.2.2))).of_enc_eq fun _ => rfl /-- The pass over the table of the gate of the top frame. -/ -theorem branch5_inSpace : +private theorem branch5_inSpace : ComputableTidilyInSpace (fun y : Tuple × Bool => if y.1.stack.isEmpty then (y.1, ([] : List Bool)) else if y.1.n₁ < tableLength y.1.ell then @@ -410,11 +419,12 @@ theorem branch5_inSpace : simp only [decide_eq_true_eq] rfl -theorem length_get_scale (R : Regs) (p : ℕ) (r r' : Fin 3) (a : ℕ) : +private theorem length_get_scale (R : Regs) (p : ℕ) (r r' : Fin 3) (a : ℕ) : ((R.scale p r a).get r').length = (R.get r').length := by fin_cases r <;> fin_cases r' <;> simp [Regs.scale, Regs.set, Regs.get] -theorem length_unitInv_le (p j : ℕ) : (encNat (unitInv p j)).length ≤ (encNat p).length + 2 := by +private theorem length_unitInv_le (p j : ℕ) : (encNat (unitInv p j)).length ≤ + (encNat p).length + 2 := by have h₁ := ComputableTidilyInO.length_encNat_mono (powMod_le (p := p) (a := j + 1) (k := p - 2) le_rfl) have h₂ := length_encNat_add_le_add p 1 @@ -422,7 +432,8 @@ theorem length_unitInv_le (p j : ℕ) : (encNat (unitInv p j)).length ≤ (encNa rw [unitInv]; omega /-- A register scaled by a residue no longer than the prime and the round of the top frame. -/ -theorem scaleT_inSpace {R : Tuple × Bool → Regs} {r : Tuple × Bool → Fin 3} {a : Tuple × Bool → ℕ} +private theorem scaleT_inSpace {R : Tuple × Bool → Regs} {r : Tuple × Bool → Fin 3} + {a : Tuple × Bool → ℕ} (hR : ComputableTidilyInSpace R encStepInT encRegs stepBudget) (hr : ComputableTidilyInSpace r encStepInT encReg stepBudget) (ha : ComputableTidilyInSpace a encStepInT encNat stepBudget) @@ -434,22 +445,23 @@ theorem scaleT_inSpace {R : Tuple × Bool → Regs} {r : Tuple × Bool → Fin 3 scale_inSpace hP ha hR hr len_le_stepBudget (mul_le_stepBudget (fun y => by rw [hlen]; have := length_get_le_regLen y.1 (r y); omega) fun y => by have := hasz y; omega) -theorem hFrame0 : ComputableTidilyInSpace (fun y : Tuple × Bool => +private theorem hFrame0 : ComputableTidilyInSpace (fun y : Tuple × Bool => (⟨0, 0, y.1.mode.neg, y.1.mode.target⟩ : Frame)) encStepInT encFrame stepBudget := (mkFrame_inSpace (hConstNat 0) (hModeFinite (encB := encFinite (Fin 4 × Bool × Fin 3)) fun m => (0, m.neg, m.target))).of_enc_eq fun _ => rfl -theorem hFrameNext : ComputableTidilyInSpace (fun y : Tuple × Bool => +private theorem hFrameNext : ComputableTidilyInSpace (fun y : Tuple × Bool => (⟨(y.1.stack.headD dfr).round + 1, 0, (y.1.stack.headD dfr).neg, (y.1.stack.headD dfr).target⟩ : Frame)) encStepInT encFrame stepBudget := (mkFrame_inSpace (hSucc hRound) (hTopFinite (encB := encFinite (Fin 4 × Bool × Fin 3)) fun g => (0, g.2.1, g.2.2))).of_enc_eq fun _ => rfl -theorem hRun : ComputableTidilyInSpace (fun _ : Tuple × Bool => runCtl) encStepInT encCtlTuple +private theorem hRun : ComputableTidilyInSpace + (fun _ : Tuple × Bool => runCtl) encStepInT encCtlTuple stepBudget := mkCtl_inSpace (hConstTag 3) (hConstNat 0) (hConstNat 0) hNil /-- The steps of the iterative procedure. -/ -theorem branch3_inSpace : +private theorem branch3_inSpace : ComputableTidilyInSpace (fun y : Tuple × Bool => runStepT y.1) encStepInT encStepOut stepBudget := by have ht := hModeFinite (encB := encReg) Mode.target diff --git a/Complexity/Computability/TreeEval/Reader/Invariant.lean b/Complexity/Computability/TreeEval/Reader/Invariant.lean index 81886f58d..b6fb570b5 100644 --- a/Complexity/Computability/TreeEval/Reader/Invariant.lean +++ b/Complexity/Computability/TreeEval/Reader/Invariant.lean @@ -64,12 +64,12 @@ def Inv (ℓ H : ℕ) (s : State) : Prop := q ≤ primeFor ℓ ∧ 2 ≤ d ∧ d ≤ q | _ => RunInv ℓ H s -theorem inv_init (ℓ H : ℕ) : Inv ℓ H init := ⟨rfl, Nat.zero_le _⟩ +private theorem inv_init (ℓ H : ℕ) : Inv ℓ H init := ⟨rfl, Nat.zero_le _⟩ variable {ℓ H : ℕ} (T : Tree ℓ H) /-- **A step keeps the invariant.** -/ -theorem inv_step {s : State} (hs : Inv ℓ H s) (hh : machine.halt s = false) : +private theorem inv_step {s : State} (hs : Inv ℓ H s) (hh : machine.halt s = false) : Inv ℓ H (machine.step s (machine.readBit T.encode s)).1 := by obtain ⟨e, h, p, R, st, m, c⟩ := s cases c with diff --git a/Complexity/Computability/TreeEval/Reader/Size.lean b/Complexity/Computability/TreeEval/Reader/Size.lean index 05540e519..4d55746ce 100644 --- a/Complexity/Computability/TreeEval/Reader/Size.lean +++ b/Complexity/Computability/TreeEval/Reader/Size.lean @@ -41,7 +41,7 @@ open Iter Turing MultiTapeTM def spaceBound (ℓ H : ℕ) : ℕ := (ℓ + H + 1) * ((encNat ℓ).length + 1) /-- A residue below the prime has at most three bits more than `ℓ`. -/ -theorem length_lt_primeFor {ℓ v : ℕ} (hv : v ≤ primeFor ℓ) : (encNat v).length ≤ +private theorem length_lt_primeFor {ℓ v : ℕ} (hv : v ≤ primeFor ℓ) : (encNat v).length ≤ (encNat ℓ).length + 3 := by refine (ComputableTidilyInO.length_encNat_mono (hv.trans (primeFor_le ℓ))).trans ?_ @@ -51,7 +51,7 @@ theorem length_lt_primeFor {ℓ v : ℕ} (hv : v ≤ primeFor ℓ) : (encNat v). rw [pow_add] omega -theorem length_encFrame_le {fr : Frame} {P : ℕ} (h : (encNat fr.round).length ≤ P) : +private theorem length_encFrame_le {fr : Frame} {P : ℕ} (h : (encNat fr.round).length ≤ P) : (encFrame fr).length ≤ 2 * P + 25 := by rw [encFrame_apply, length_encPair] have := length_encFinite_lt (Frame.equiv fr).2 @@ -60,20 +60,20 @@ theorem length_encFrame_le {fr : Frame} {P : ℕ} (h : (encNat fr.round).length simp only [Frame.equiv, Equiv.coe_fn_mk] at this ⊢ omega -theorem length_encList_frames_le {st : List Frame} {P : ℕ} +private theorem length_encList_frames_le {st : List Frame} {P : ℕ} (h : ∀ fr ∈ st, (encNat fr.round).length ≤ P) : (encList encFrame st).length ≤ st.length * (4 * P + 51) := (length_encList_le encFrame st fun fr hfr => length_encFrame_le (h fr hfr)).trans_eq (by ring) -theorem length_encMode_lt (m : Mode) : (encMode m).length < 7 := by +private theorem length_encMode_lt (m : Mode) : (encMode m).length < 7 := by have := length_encFinite_lt m have hc : Nat.card Mode = 7 := by rw [Nat.card_congr Mode.equiv]; simp rw [hc] at this exact this -theorem length_encTag_lt (t : Fin 7) : (encFinite (Fin 7) t).length < 7 := by +private theorem length_encTag_lt (t : Fin 7) : (encFinite (Fin 7) t).length < 7 := by simpa using length_encFinite_lt t /-- The bounds on the components of a state that satisfies the invariant. -/ @@ -90,7 +90,8 @@ structure Bounds (ℓ H : ℕ) (s : State) : Prop where acc : s.ctl.toTuple.2.2.2.length ≤ ℓ ∧ (encList encNat s.ctl.toTuple.2.2.2).length ≤ ℓ * (2 * ((encNat ℓ).length + 3) + 1) -theorem bounds_regs_wf {ℓ p : ℕ} {R : Regs} (hR : R.WF p ℓ) (hp : p ≤ primeFor ℓ) (r : Fin 3) : +private theorem bounds_regs_wf {ℓ p : ℕ} {R : Regs} (hR : R.WF p ℓ) (hp : p ≤ primeFor ℓ) + (r : Fin 3) : (R.get r).length ≤ ℓ ∧ (encList encNat (R.get r)).length ≤ ℓ * (2 * ((encNat ℓ).length + 3) + 1) := by obtain ⟨hlen, hlt⟩ := hR r diff --git a/Complexity/Computability/USTCON/Reader/Cert.lean b/Complexity/Computability/USTCON/Reader/Cert.lean index 1e2f579de..d78ea5455 100644 --- a/Complexity/Computability/USTCON/Reader/Cert.lean +++ b/Complexity/Computability/USTCON/Reader/Cert.lean @@ -253,7 +253,7 @@ private theorem labelOfNat_eq (w : ℕ) : /-- **The label of a digit** is computed by a finite-state fold over the binary digits of `w`, within work space linear in their number. -/ -theorem labelOfNat_inSpace : +private theorem labelOfNat_inSpace : ComputableTidilyInSpace labelOfNat encNat encLab fun w => (encNat w).length := by have hfold := of_inO (ComputableTidilyInO.foldl_bits_finite (encFinite (ZMod numLabels × ZMod numLabels)) modStep (0, 1)) @@ -468,7 +468,8 @@ private theorem stepT_inSpace : ComputableTidilyInSpace stepT encStepIn (encPair noncomputable def stateBudget (q : State) : ℕ := stepBudget (q.toTuple, false) -theorem stepBudget_bool (x : Tuple) (b : Bool) : stepBudget (x, b) = stepBudget (x, false) := by +private theorem stepBudget_bool (x : Tuple) (b : Bool) : stepBudget (x, b) = stepBudget + (x, false) := by cases b <;> simp [stepBudget, encBool_apply] theorem halt_inSpace : ComputableTidilyInSpace machine.halt encState encBool stateBudget := diff --git a/Complexity/Computability/USTCON/Reader/Invariant.lean b/Complexity/Computability/USTCON/Reader/Invariant.lean index da0c498b9..43ac1d0da 100644 --- a/Complexity/Computability/USTCON/Reader/Invariant.lean +++ b/Complexity/Computability/USTCON/Reader/Invariant.lean @@ -268,7 +268,7 @@ private theorem inv_check {q : State} (hb : Bounds I q) (hc : q.ctl = .check) (h hb.lower, hb.frames⟩, hp⟩ /-- **The invariant is kept by a step.** -/ -theorem inv_step {q : State} (h : Inv I q) (hd : q.ctl ≠ .done) : +private theorem inv_step {q : State} (h : Inv I q) (hd : q.ctl ≠ .done) : Inv I (step q (machine.readBit I.encode q)).1 := by obtain ⟨hb, hp⟩ := h rcases hc : q.ctl with _ | _ | _ | _ | _ | _ | _ | _ | _ | _ <;> @@ -285,7 +285,7 @@ theorem inv_step {q : State} (h : Inv I q) (hd : q.ctl ≠ .done) : · exact absurd hc hd /-- The initial state satisfies the invariant. -/ -theorem inv_init : Inv I init := by +private theorem inv_init : Inv I init := by have hn := I.n_pos exact ⟨⟨Nat.zero_le _, Nat.zero_le _, Nat.zero_le _, Nat.zero_le _, Nat.zero_le _, Nat.zero_le _, Nat.zero_le _, Nat.zero_le _, Nat.zero_le _, hn, hn, Nat.zero_le _, Nat.zero_le _⟩, rfl⟩ @@ -348,7 +348,7 @@ def stateConst : ℕ := /-- **The states satisfying the bounds have `O(log n)` bits**: at most a constant times the number of binary digits of `n`, plus one. -/ -theorem length_encState_le_of_bounds {q : State} (hb : Bounds I q) : +private theorem length_encState_le_of_bounds {q : State} (hb : Bounds I q) : (encState q).length ≤ stateConst * (Nat.size I.n + 1) := by set a := Nat.size I.n have hD : depthOf I = 16 * a + 524 := rfl