Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 8 additions & 31 deletions Complexity/Computability/Complexity/Classes/WPP.lean
Original file line number Diff line number Diff line change
Expand Up @@ -339,34 +339,6 @@ theorem mem_LWPP_of_finset_targets {ι : Type*} (s : Finset ι) {g : α → ℤ}

/-! ### Unary-indexed target normalization and `LWPP` reduction closure -/

private theorem prod_map_ne_zero {γ : Type*} {f : γ → ℤ} {l : List γ}
(h : ∀ x ∈ l, f x ≠ 0) : (l.map f).prod ≠ 0 := by
induction l with
| nil => simp
| cons x l ih =>
simp only [List.map_cons, List.prod_cons]
exact mul_ne_zero (h x (by simp)) (ih fun y hy => h y (by simp [hy]))

private theorem mul_prod_filter_range_ne (f : ℕ → ℤ) {K m : ℕ} (hm : m < K) :
f m * (((List.range K).filter (fun i => decide (i ≠ m))).map f).prod =
((List.range K).map f).prod := by
induction K with
| zero => lia
| succ K ih =>
rw [List.range_succ, List.filter_append, List.map_append, List.prod_append,
List.map_append, List.prod_append]
rcases Nat.lt_succ_iff_lt_or_eq.mp hm with hlt | rfl
· have hne : decide (K ≠ m) = true := decide_eq_true (by lia)
simp only [List.filter_cons, hne, ↓reduceIte, List.filter_nil, List.map_cons, List.map_nil,
List.prod_cons, List.prod_nil, mul_one]
rw [← mul_assoc, ih hlt]
· have hfilt : (List.range m).filter (fun i => decide (i ≠ m)) = List.range m :=
List.filter_eq_self.mpr fun i hi => decide_eq_true (Nat.ne_of_lt (List.mem_range.mp hi))
simp only [hfilt, List.filter_cons, ne_eq, not_true_eq_false, decide_false,
Bool.false_eq_true, ↓reduceIte, List.filter_nil, List.map_nil, List.prod_nil, mul_one,
List.map_cons, List.prod_cons]
ring

/-- **Unary-indexed target normalization for `LWPP`:** if a `GapP` function takes `0` outside `A`
and `f (k a)` on `A`, where `f : ℕ → ℤ` is a nonzero unary-input polynomial-time target and
`k : α → ℕ` is computable in polynomial time in unary, then multiplying the gap by the
Expand All @@ -392,7 +364,7 @@ theorem mem_LWPP_of_polyTime_index {g : α → ℤ} {f : ℕ → ℤ} {k : α
ComputableTidilyInPolyTime.intBin_prod.comp
((ComputableTidilyInPolyTime.map hf).comp
(ComputableTidilyInPolyTime.range.comp hbound))
have hFn (n : ℕ) : F n ≠ 0 := prod_map_ne_zero fun _ _ => hn _
have hFn (n : ℕ) : F n ≠ 0 := List.prod_ne_zero (by simp [hn])
let h (a : α) : ℤ :=
(((List.range (bound (enc a).length)).filter (fun i => decide (i ≠ k a))).map f).prod
have hlist : ComputableTidilyInPolyTime
Expand All @@ -409,8 +381,13 @@ theorem mem_LWPP_of_polyTime_index {g : α → ℤ} {f : ℕ → ℤ} {k : α
ComputableTidilyInPolyTime.intBin_prod.comp
((ComputableTidilyInPolyTime.map hf).comp
(ComputableTidilyInPolyTime.filterWithInput hlist htest))
have hmul (a : α) : f (k a) * h a = F (enc a).length :=
mul_prod_filter_range_ne f (hlt a)
have hmul (a : α) : f (k a) * h a = F (enc a).length := by
have herase :
(List.range (bound (enc a).length)).filter (fun i => decide (i ≠ k a)) =
(List.range (bound (enc a).length)).erase (k a) := by
rw [List.nodup_range.erase_eq_filter]
exact List.filter_congr fun i _ => by simp [bne, beq_eq_decide]
simpa only [h, F, herase] using List.prod_map_erase f (List.mem_range.mpr (hlt a))
refine ⟨g * h, GapP.mul_mem hg (GapP.of_polyTime hh), F, .of_tidy hF, hFn, fun a => ?_,
fun a => ?_⟩
· rcases hr a with hz | hfk
Expand Down
39 changes: 8 additions & 31 deletions Complexity/Computability/Complexity/Classes/WPP/Lowness.lean
Original file line number Diff line number Diff line change
Expand Up @@ -460,34 +460,6 @@ theorem PPWithOracle_eq_PP_of_mem_SPP (hA : A ∈ SPP encBits) (enc : α ↪ Lis

/-! ### `LWPP` scaling simulation and oracle lowness (FFK94, Section 5) -/

private theorem prod_map_ne_zero {γ : Type*} {f : γ → ℤ} {l : List γ}
(h : ∀ x ∈ l, f x ≠ 0) : (l.map f).prod ≠ 0 := by
induction l with
| nil => simp only [List.map_nil, List.prod_nil, ne_eq, one_ne_zero, not_false_eq_true]
| cons x l ih =>
simp only [List.map_cons, List.prod_cons]
exact mul_ne_zero (h x List.mem_cons_self) (ih fun y hy => h y (List.mem_cons_of_mem x hy))

private theorem mul_prod_filter_range_ne (f : ℕ → ℤ) {K m : ℕ} (hm : m < K) :
f m * (((List.range K).filter (fun i => decide (i ≠ m))).map f).prod =
((List.range K).map f).prod := by
induction K with
| zero => lia
| succ K ih =>
rw [List.range_succ, List.filter_append, List.map_append, List.prod_append,
List.map_append, List.prod_append]
rcases Nat.lt_succ_iff_lt_or_eq.mp hm with hlt | rfl
· have hne : decide (K ≠ m) = true := decide_eq_true (by lia)
simp only [List.filter_cons, hne, ↓reduceIte, List.filter_nil, List.map_cons, List.map_nil,
List.prod_cons, List.prod_nil, mul_one]
rw [← mul_assoc, ih hlt]
· have hfilt : (List.range m).filter (fun i => decide (i ≠ m)) = List.range m :=
List.filter_eq_self.mpr fun i hi => decide_eq_true (Nat.ne_of_lt (List.mem_range.mp hi))
simp only [hfilt, List.filter_cons, ne_eq, not_true_eq_false, decide_false,
Bool.false_eq_true, ↓reduceIte, List.filter_nil, List.map_nil, List.prod_nil, mul_one,
List.map_cons, List.prod_cons]
ring

private theorem exists_mul_mem_GapP_of_sharpPWithOracle_of_mem_LWPP (hA : A ∈ LWPP encBits)
{c : α → ℕ} (hc : c ∈ SharpPWithOracle A enc) :
∃ S : ℕ → ℤ, ComputableTidilyInPolyTime S encUnary encIntBin ∧
Expand All @@ -514,7 +486,7 @@ private theorem exists_mul_mem_GapP_of_sharpPWithOracle_of_mem_LWPP (hA : A ∈
ComputableTidilyInPolyTime.intBin_prod.comp
((ComputableTidilyInPolyTime.map hf).comp
(ComputableTidilyInPolyTime.range.comp hbound))
have hDn (n : ℕ) : D n ≠ 0 := prod_map_ne_zero fun _ _ => hfn _
have hDn (n : ℕ) : D n ≠ 0 := List.prod_ne_zero (by simp [hfn])
let S : ℕ → ℤ := fun n => D n ^ τ n
have hS : ComputableTidilyInPolyTime S encUnary encIntBin := hD.intBin_pow' hτ
have hSn (n : ℕ) : S n ≠ 0 := pow_ne_zero (τ n) (hDn n)
Expand Down Expand Up @@ -557,8 +529,13 @@ private theorem exists_mul_mem_GapP_of_sharpPWithOracle_of_mem_LWPP (hA : A ∈
have hH_exact (q : List Bool) (hq : q.length ≤ T a) :
H (a, q) = open Classical in if q ∈ A then D (enc a).length else 0 := by
have hlt : q.length < bound (enc a).length := Nat.lt_succ_of_le hq
have hmul : f q.length * K (a, q) = D (enc a).length :=
mul_prod_filter_range_ne f hlt
have hmul : f q.length * K (a, q) = D (enc a).length := by
have herase :
(List.range (bound (enc a).length)).filter (fun i => decide (i ≠ q.length)) =
(List.range (bound (enc a).length)).erase q.length := by
rw [List.nodup_range.erase_eq_filter]
exact List.filter_congr fun i _ => by simp [bne, beq_eq_decide]
simpa only [K, D, herase] using List.prod_map_erase f (List.mem_range.mpr hlt)
dsimp only [H]
rw [hg_eq q]
split_ifs
Expand Down
Loading