Guest User

Untitled

a guest
Apr 17th, 2021
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.26 KB | None | 0 0
  1. import data.fintype.basic
  2. import data.fintype.card
  3. import data.finset.basic
  4.  
  5. import tactic.ring
  6.  
  7. open equiv fintype
  8.  
  9. section definitions
  10.  
  11. def is_derangement {α : Type*} (f : perm α) : Prop := (∀ x : α, f x ≠ x)
  12.  
  13. def derangements (α : Type*) := {f : perm α // is_derangement f}
  14.  
  15. -- TODO fintype seems too restrictive; how do i correctly loosen this?
  16. variables {α : Type*} [decidable_eq α] [fintype α]
  17.  
  18. instance derangement_decidable : decidable_pred (λ f : perm α, is_derangement f) :=
  19. begin
  20. intro f,
  21. apply fintype.decidable_forall_fintype,
  22. end
  23.  
  24. instance derangements_fintype : fintype (derangements α) := begin
  25. exact subtype.fintype _,
  26. end
  27.  
  28. end definitions
  29.  
  30. section nice_lemmas
  31. -- here's some functions that i may or may not use
  32. -- TODO delete the ones i don't, and rename the rest to follow lean conventions
  33.  
  34. universe u
  35. variables {α β : Type u}
  36.  
  37. def derangement_congr (e : α ≃ β) : (derangements α) ≃ (derangements β) :=
  38. begin
  39. refine subtype_equiv (perm_congr e) _,
  40. intro σ,
  41. unfold is_derangement,
  42. rw ← not_iff_not,
  43. push_neg,
  44. split,
  45. { rintro ⟨a, ha⟩,
  46. use (e a),
  47. simp,
  48. assumption },
  49. { rintro ⟨b, hb⟩,
  50. use (e.symm b),
  51. conv_rhs { rw ← hb },
  52. simp },
  53. end
  54.  
  55. def perm_subtype_preimage {p : α → Prop} [decidable_pred p] (f₀ : perm {x // p x}) :
  56. {f : perm α // f ∘ coe = coe ∘ f₀} ≃ perm {x // ¬ p x} :=
  57. begin
  58. -- we want to use equiv.set.compl:
  59. -- {e : α ≃ β // ∀ x : s, e x = e₀ x} ≃ ((sᶜ : set α) ≃ (tᶜ : set β))
  60. let s : set α := {a : α | p a},
  61.  
  62. transitivity {f : perm α // ∀ x : s, f x = f₀ x},
  63. {
  64. apply subtype_equiv_right _,
  65. intro f,
  66. split,
  67. {
  68. rintros hf x,
  69. calc f x = (f ∘ coe) x : rfl
  70. ... = (coe ∘ f₀) x : by rw hf
  71. ... = f₀ x : rfl,
  72. },
  73. {
  74. intro hf,
  75. funext,
  76. simp,
  77. rw hf _,
  78. }
  79. },
  80.  
  81. transitivity perm (sᶜ : set α),
  82. {
  83. exact equiv.set.compl f₀,
  84. },
  85.  
  86. apply perm_congr,
  87. refl,
  88. end
  89.  
  90. end nice_lemmas
  91.  
  92. section counting
  93.  
  94. -- TODO can i hide this in some way? it's computationally expensive...
  95. def num_derangements (n : ℕ) : ℕ := fintype.card (derangements (fin n))
  96.  
  97. lemma num_derangements_invariant {α : Type} [fintype α] [decidable_eq α] :
  98. fintype.card (derangements α) = num_derangements (fintype.card α) :=
  99. begin
  100. unfold num_derangements,
  101. rw fintype.card_eq,
  102. obtain ⟨x⟩ := equiv_fin α, -- TODO what's going on here? it's related to non-computability i think
  103. use derangement_congr x,
  104. end
  105.  
  106. lemma num_derangements_invariant_apply {α : Type} [fintype α] [decidable_eq α]
  107. {n : ℕ} (hα : n = fintype.card α) :
  108. fintype.card (derangements α) = num_derangements n :=
  109. begin
  110. rw hα,
  111. exact num_derangements_invariant,
  112. end
  113.  
  114. end counting
  115.  
  116. section type1
  117.  
  118. variables {α : Type*} [decidable_eq α]
  119.  
  120. def perm_ignore_two_cycle (a b : α) :
  121. { f : perm α // f a = b ∧ f b = a } ≃ perm {k : α // k ≠ a ∧ k ≠ b} :=
  122. begin
  123. let pred : α → Prop := λ k, k = a ∨ k = b,
  124. let pred_a : pred a := by {left, refl},
  125. let pred_b : pred b := by {right, refl},
  126.  
  127. let a_and_b := {k : α // pred k},
  128. let swap : perm a_and_b := equiv.swap ⟨a, pred_a⟩ ⟨b, pred_b⟩,
  129.  
  130. transitivity {f : perm α // f ∘ coe = coe ∘ swap},
  131. {
  132. refine subtype_equiv_right _,
  133. intro f,
  134. split,
  135. {
  136. rintro ⟨hf_a, hf_b⟩,
  137. funext,
  138. cases x with x x_pred,
  139. simp,
  140. dsimp [swap],
  141. cases x_pred with x_eq_a x_eq_b,
  142. {
  143. -- why does subst work when rw doesn't??
  144. subst x_eq_a,
  145. simp,
  146. assumption,
  147. },
  148. {
  149. subst x_eq_b,
  150. simp,
  151. assumption,
  152. },
  153. },
  154. {
  155. intro hf,
  156. split,
  157. {
  158. let a' : a_and_b := ⟨a, pred_a⟩,
  159. calc f a = (f ∘ coe) a' : by simp
  160. ... = coe (swap a') : by rw hf
  161. ... = b : by simp
  162. },
  163. {
  164. let b' : a_and_b := ⟨b, pred_b⟩,
  165. calc f b = (f ∘ coe) b' : by simp
  166. ... = coe (swap b') : by rw hf
  167. ... = a : by simp
  168. }
  169. }
  170. },
  171.  
  172. transitivity perm {k : α // ¬ pred k},
  173. {
  174. exact perm_subtype_preimage swap,
  175. },
  176.  
  177. apply perm_congr,
  178. refine subtype_equiv_right _,
  179. intro x,
  180. dsimp [pred],
  181. push_neg,
  182. end
  183.  
  184. -- TODO show that the perm_ignore_two_cycle preserves derangements
  185. def derangement_ignore_two_cycle_helper (a b : α) (hab : a ≠ b) :
  186. ∀ f : { f : perm α // f a = b ∧ f b = a },
  187. is_derangement f.val ↔ is_derangement (perm_ignore_two_cycle a b f) :=
  188. begin
  189. intro f,
  190.  
  191. have key : ∀ x : {x // x ≠ a ∧ x ≠ b}, f x = (perm_ignore_two_cycle a b f) x,
  192. {
  193. dsimp [perm_ignore_two_cycle, subtype_equiv_right, perm_subtype_preimage, equiv.set.compl],
  194. simp,
  195. },
  196.  
  197. split,
  198. {
  199. intros h_derangement x,
  200. apply_fun subtype.val,
  201. simp,
  202. rw ← key x,
  203. exact h_derangement x,
  204. },
  205. {
  206. intros h_derangement x,
  207. by_cases H : x ≠ a ∧ x ≠ b,
  208. {
  209. -- TODO this is a silly juggle to avoid 'motive is not type correct'
  210. intro contra,
  211. specialize h_derangement ⟨x, H⟩,
  212. revert h_derangement,
  213. contrapose!,
  214.  
  215. intro _,
  216. apply subtype.coe_injective,
  217. rw ← key _,
  218. exact contra,
  219. },
  220. {
  221. rw not_and_distrib at H,
  222. push_neg at H,
  223. cases H with Ha Hb,
  224. {
  225. rw [Ha, f.property.left],
  226. exact hab.symm,
  227. },
  228. {
  229. rw [Hb, f.property.right],
  230. exact hab,
  231. }
  232. }
  233. },
  234. end
  235.  
  236. def derangement_ignore_two_cycle (a b : α) (hab : a ≠ b) :
  237. { f : derangements α // f.val a = b ∧ f.val b = a } ≃ derangements {k : α // k ≠ a ∧ k ≠ b} :=
  238. begin
  239. -- TODO this is a mess. i gotta specify these predicates explicitly, which
  240. -- seems suboptimal... why can't it infer them?
  241. let foo : perm α → Prop := λ f, f a = b ∧ f b = a,
  242. let bar : {f : perm α // foo f} → Prop := λ f, is_derangement (perm_ignore_two_cycle a b f),
  243.  
  244. transitivity {x // is_derangement x ∧ foo x},
  245. {
  246. exact subtype_subtype_equiv_subtype_inter _ foo,
  247. },
  248.  
  249. -- TODO this seems... verbose
  250. -- but it's less verbose than the equivalent calc block would be, i think?
  251. apply equiv.trans _ (subtype_equiv_of_subtype (perm_ignore_two_cycle a b)),
  252. apply equiv.trans _ (subtype_equiv_right (derangement_ignore_two_cycle_helper a b hab)),
  253. apply equiv.trans _ (subtype_subtype_equiv_subtype_inter _ _).symm,
  254.  
  255. refine subtype_equiv_right _,
  256. intro x,
  257. tauto,
  258. end
  259.  
  260. end type1
  261.  
  262. section recursion
  263.  
  264. @[derive decidable_pred]
  265. def type1 {n : ℕ} : derangements (fin(n+1)) → Prop := λ σ, σ.val (σ.val 0) = 0
  266.  
  267. @[derive decidable_pred]
  268. def type2 {n : ℕ} : derangements (fin(n+1)) → Prop := λ σ, ¬type1 σ
  269.  
  270. def value_at_zero {n : ℕ} (σ : derangements (fin(n+1))) : fin(n+1) := σ.val 0
  271.  
  272.  
  273. lemma size_of_type1' {n : ℕ} (m : fin(n+1)) :
  274. fintype.card {σ : derangements (fin(n+2)) // type1 σ ∧ value_at_zero σ = m.succ} = num_derangements n :=
  275. begin
  276. have h_0_ne_m := fin.succ_ne_zero m,
  277.  
  278. have : fintype.card {k : fin(n+2) // k ≠ 0 ∧ k ≠ m.succ } = n,
  279. {
  280. sorry, -- TODO this is obvious to the human, but i don't know how to
  281. -- 'get into' the start of this proof. must be doable! but how? :\
  282. },
  283.  
  284. -- TODO this is way too verbose. are there tricks to make this easier?
  285. rw ← num_derangements_invariant_apply this.symm,
  286. apply card_congr,
  287. apply equiv.trans _ (derangement_ignore_two_cycle 0 m.succ h_0_ne_m.symm),
  288. apply subtype_equiv_right,
  289.  
  290. intro σ,
  291. split,
  292. {
  293. rintro ⟨h_split, h_m⟩,
  294. split,
  295. { exact h_m },
  296. { rw ← h_m, exact h_split },
  297. },
  298. {
  299. rintro ⟨h_0, h_m⟩,
  300. split,
  301. { unfold1 type1, rw h_0, exact h_m },
  302. { exact h_0 }
  303. }
  304. end
  305.  
  306. lemma size_of_type1 {n : ℕ} :
  307. fintype.card {σ : derangements (fin(n+2)) // type1 σ} = (n + 1) * num_derangements n :=
  308. begin
  309. let lhs := {σ : derangements (fin(n+2)) // type1 σ},
  310. have : lhs ≃ Σ m : fin(n+2), {σ : lhs // value_at_zero σ.val = m}, from
  311. (sigma_preimage_equiv _).symm,
  312. rw card_congr this,
  313. rw fintype.card_sigma,
  314. rw fin.sum_univ_succ,
  315.  
  316. have : {σ : lhs // value_at_zero σ.val = 0} ≃ empty,
  317. {
  318. apply equiv_empty,
  319. intro σ,
  320. have h_eq_0 : σ.val.val.val 0 = 0 := σ.property,
  321. have h_ne_0 : σ.val.val.val 0 ≠ 0 := σ.val.val.property 0,
  322. exact h_ne_0 h_eq_0,
  323. },
  324. rw card_congr this,
  325.  
  326. have : ∀ m : fin(n+1), card {σ : lhs // value_at_zero σ.val = m.succ} = num_derangements n,
  327. {
  328. intro m,
  329. rw ← size_of_type1' m,
  330. apply card_congr,
  331. exact subtype_subtype_equiv_subtype_inter type1 (λ σ, value_at_zero σ = m.succ),
  332. },
  333. simp_rw this,
  334. simp,
  335. end
  336.  
  337. lemma size_of_type2 {n : ℕ} :
  338. fintype.card {σ : derangements (fin(n+2)) // type2 σ} = (n + 1) * num_derangements (n+1) :=
  339. begin
  340. sorry,
  341. end
  342.  
  343.  
  344. lemma num_derangements_recursive (n : ℕ) :
  345. num_derangements (n+2) = (n + 1) * (num_derangements n + num_derangements (n+1)) :=
  346. begin
  347. -- TODO would it be better to get subsets of perm (fin(_)) instead?
  348. let splitting_pred : derangements (fin(n+2)) → Prop := λ σ, σ.val (σ.val 0) = 0,
  349. let type1_derangements := {σ : derangements (fin(n+2)) // type1 σ},
  350. let type2_derangements := {σ : derangements (fin(n+2)) // type2 σ},
  351.  
  352. calc num_derangements (n+2) = fintype.card ( derangements (fin(n+2)) ) : rfl
  353. ... = fintype.card ( type1_derangements ⊕ type2_derangements ) : card_congr (sum_compl splitting_pred).symm
  354. ... = fintype.card type1_derangements + fintype.card type2_derangements : fintype.card_sum _ _
  355. ... = (n+1) * num_derangements n + (n+1) * num_derangements (n+1) : by rw [size_of_type1, size_of_type2]
  356. ... = (n+1) * (num_derangements n + num_derangements (n+1)) : by ring,
  357. -- done!
  358. end
  359.  
  360. end recursion
  361.  
  362. section explicit
  363.  
  364. -- TODO theorem about alternating sum of stuff
  365.  
  366. end explicit
  367.  
  368. #eval num_derangements 0
  369. #eval num_derangements 1
  370. #eval num_derangements 2
  371. #eval num_derangements 3
  372. #eval num_derangements 4
  373. #eval num_derangements 5
  374.  
Advertisement
Add Comment
Please, Sign In to add comment