Advertisement
Guest User

Derangements formula

a guest
May 4th, 2021
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.64 KB | None | 0 0
  1. import data.equiv.basic
  2. import data.fintype.basic
  3. import data.fintype.card
  4. import tactic.equiv_rw
  5. import tactic.field_simp
  6. import tactic.ring
  7.  
  8. open equiv fintype
  9.  
  10. section definitions
  11.  
  12. def is_derangement {α : Type*} (f : perm α) : Prop := (∀ x : α, f x ≠ x)
  13.  
  14. def derangements (α : Type*) := {f : perm α | is_derangement f}
  15.  
  16. end definitions
  17.  
  18.  
  19. section derangement_lemmas
  20.  
  21. def derangement_congr {α β : Type*} (e : α ≃ β) : (derangements α ≃ derangements β) :=
  22. begin
  23. refine subtype_equiv (perm_congr e) _,
  24. intro f,
  25. unfold derangements is_derangement,
  26. simp,
  27. rw ← not_iff_not,
  28. push_neg,
  29. split,
  30. {
  31. rintro ⟨x, hx_fixed⟩,
  32. use e x,
  33. simp [hx_fixed],
  34. },
  35. {
  36. rintro ⟨y, hy_fixed⟩,
  37. use e.symm y,
  38. apply e.injective,
  39. simp [hy_fixed],
  40. }
  41. end
  42.  
  43. end derangement_lemmas
  44.  
  45.  
  46. section ignore_two_cycle
  47.  
  48. variables {α : Type*} [decidable_eq α]
  49.  
  50. def is_two_cycle {α : Type*} (f : perm α) (a b : α) : Prop := f a = b ∧ f b = a
  51.  
  52. def perm_ignore_two_cycle (a b : α) :
  53. { f : perm α | is_two_cycle f a b } ≃ perm ({a, b}ᶜ : set α) :=
  54. begin
  55. let a_and_b : set α := {a, b},
  56.  
  57. let swap : perm α := equiv.swap a b,
  58. let swap' : perm a_and_b :=
  59. begin
  60. apply perm.subtype_perm swap,
  61. intro x,
  62. simp,
  63. split,
  64. {
  65. intro x_in,
  66. cases x_in; { simp [x_in] },
  67. },
  68. {
  69. contrapose!,
  70. rintro ⟨x_ne_a, x_ne_b⟩,
  71. simp [swap_apply_of_ne_of_ne x_ne_a x_ne_b],
  72. tauto,
  73. }
  74. end,
  75.  
  76. transitivity {f : perm α // ∀ x : a_and_b, f x = swap' x},
  77. {
  78. apply subtype_equiv_right,
  79. intro σ,
  80. simp [is_two_cycle],
  81. },
  82. {
  83. -- TODO why can't it infer this is decidable?
  84. haveI : decidable_pred a_and_b := by
  85. {
  86. dsimp [decidable_pred, a_and_b],
  87. intro x,
  88. apply set.decidable_mem,
  89. },
  90. exact equiv.set.compl swap',
  91. },
  92. end
  93.  
  94. -- TODO make this a simp lemma?
  95. lemma perm_ignore_two_cycle_eq (a b : α) (f : perm α) (hf : is_two_cycle f a b) (c : ({a, b}ᶜ : set α)):
  96. ((perm_ignore_two_cycle a b) ⟨f, hf⟩ c : α) = f c :=
  97. begin
  98. simp [perm_ignore_two_cycle, equiv.set.compl],
  99. end
  100.  
  101. -- TODO this name definitely isn't up to snuff...
  102. lemma perm_ignore_two_cycle_derangement_iff (a b : α) (hab : a ≠ b) (f : perm α) (hf : is_two_cycle f a b) :
  103. is_derangement f ↔ is_derangement ((perm_ignore_two_cycle a b) ⟨f, hf⟩) :=
  104. begin
  105. split,
  106. {
  107. rintros f_derangement ⟨x, hx⟩,
  108. apply subtype.ne_of_val_ne,
  109. simp [perm_ignore_two_cycle_eq, f_derangement x],
  110. },
  111. {
  112. -- easier to show that fixed point in f implies a fixed point
  113. -- in (f without a↔b)
  114. contrapose!,
  115. simp [is_derangement],
  116.  
  117. --intro our fixed point and show that it's neither a nor b
  118. intros x x_fixed,
  119. have x_ne_a_b : ¬(x = a ∨ x = b),
  120. {
  121. intro contra,
  122. unfold is_two_cycle at hf,
  123. cases contra; { rw contra at x_fixed, cc },
  124. },
  125.  
  126. use [x, x_ne_a_b],
  127. simp [subtype.ext_iff, perm_ignore_two_cycle_eq, x_fixed],
  128. }
  129. end
  130.  
  131. end ignore_two_cycle
  132.  
  133.  
  134. section splicing
  135.  
  136. variables {α : Type*} [decidable_eq α]
  137.  
  138. -- TODO feels like this should already exist? something something equiv_functor?
  139. def equiv_compose (f : perm α) : perm (perm α) :=
  140. {
  141. to_fun := λ g, g.trans f,
  142. inv_fun := λ g, g.trans f.symm,
  143. left_inv := λ g, by { simp [trans_assoc] },
  144. right_inv := λ g, by { simp [trans_assoc] },
  145. }
  146.  
  147. -- TODO: maybe this should look more like (or even use!) `equiv.perm.decompose_option`
  148. def perm_splice_out (a : α) :
  149. ∀ b : α, { f : perm α | f a = b } ≃ perm ({a}ᶜ : set α) :=
  150. begin
  151. intro b,
  152. let just_a : set α := {a},
  153.  
  154. transitivity {f : perm α // ∀ x : just_a, f x = equiv.refl just_a x},
  155. {
  156. -- we want to modify each permutation by composing it with (swap a and b)
  157. let compose_with_swap : perm (perm α) := equiv_compose (equiv.swap a b),
  158.  
  159. apply equiv.trans (subtype_equiv_of_subtype' compose_with_swap) _,
  160. apply subtype_equiv_right,
  161. simp [compose_with_swap, equiv_compose],
  162.  
  163. intro f,
  164. rw apply_eq_iff_eq_symm_apply,
  165. simp,
  166. },
  167. {
  168. apply equiv.set.compl,
  169. }
  170. end
  171.  
  172. -- TODO should this be coe instead of val?
  173. -- either way it should be consistent with perm_ignore_two_cycle_eq
  174. lemma nicer_splice_lemma (a b : α) (f : perm α) (fa_eq_b : f a = b) (x : α) (hx : x ≠ a) :
  175. (perm_splice_out a b ⟨f, fa_eq_b⟩ ⟨x, hx⟩).val = (swap a b) (f x) :=
  176. begin
  177. simp [perm_splice_out, equiv.set.compl,
  178. subtype_equiv_of_subtype', subtype_equiv_of_subtype,
  179. equiv_compose],
  180. end
  181.  
  182. lemma nice_splice_lemma (a b : α) (hab : a ≠ b) (f : perm α) (fa_eq_b : f a = b) :
  183. f b ≠ a ∧ is_derangement f ↔
  184. (perm_splice_out a b) ⟨f, fa_eq_b⟩ ∈ derangements ({a}ᶜ : set α) :=
  185. begin
  186. -- again, easier to show that fixed points lead to other fixed points
  187. rw ← not_iff_not,
  188. simp [derangements, is_derangement],
  189. rw imp_iff_not_or,
  190. simp,
  191.  
  192. split,
  193. {
  194. -- if f has a fixed point, then so does (spliced-f). also happens if f b = a,
  195. -- because then b is a fixed point.
  196. rw or_imp_distrib,
  197. split,
  198. {
  199. intro fb_eq_a,
  200. use [b, hab.symm],
  201. simp [subtype.ext_iff_val, nicer_splice_lemma],
  202. apply_fun (swap a b),
  203. simpa,
  204. },
  205. {
  206. rintro ⟨x, x_fixed⟩,
  207. have x_ne_a : x ≠ a,
  208. {
  209. intro contra,
  210. rw contra at x_fixed,
  211. cc,
  212. },
  213. have x_ne_b : x ≠ b,
  214. {
  215. intro contra,
  216. rw contra at x_fixed,
  217. have : f a = f b, by cc,
  218. exact hab (f.injective this),
  219. },
  220.  
  221. use [x, x_ne_a],
  222. simp [subtype.ext_iff_val, nicer_splice_lemma],
  223. apply_fun (swap a b),
  224. simp [x_fixed, swap_apply_of_ne_of_ne x_ne_a x_ne_b],
  225. }
  226. },
  227. {
  228. -- if (spliced-f) has a fixed point, it came from a pre-existing
  229. -- one, or it's b
  230. rintro ⟨x, x_ne_a, x_fixed⟩,
  231. simp [subtype.ext_iff_val, nicer_splice_lemma] at x_fixed,
  232. apply_fun (swap a b) at x_fixed,
  233. simp at x_fixed,
  234.  
  235. by_cases x_vs_b : x = b,
  236. {
  237. left,
  238. simp [x_vs_b] at x_fixed,
  239. assumption,
  240. },
  241. {
  242. right,
  243. use x,
  244. rw swap_apply_of_ne_of_ne x_ne_a x_vs_b at x_fixed,
  245. assumption,
  246. }
  247. }
  248. end
  249.  
  250.  
  251. end splicing
  252.  
  253.  
  254.  
  255. section recursion
  256.  
  257. variables {α : Type*} [decidable_eq α]
  258.  
  259. def everything_but (a : α) : set α := {a}ᶜ
  260.  
  261. def neither_of (a : α) (b : everything_but a) : set α := {a, b}ᶜ
  262.  
  263. lemma special_1 (a : α) (b : everything_but a) :
  264. {f : derangements α // is_two_cycle ↑f a b} ≃ derangements (neither_of a b) :=
  265. begin
  266. cases b with b hab,
  267.  
  268. -- TODO there's a few places i have to take subtypes of subtypes and merge
  269. -- their properties. is there an easier way to do this? (is that what `equiv_rw` can do?)
  270. transitivity {f' : {f : perm α // is_two_cycle f a b} // is_derangement f'.val},
  271. {
  272. apply equiv.trans
  273. (subtype_subtype_equiv_subtype_inter _ (λ f, is_two_cycle f a b))
  274. _,
  275. apply equiv.trans _ (subtype_subtype_equiv_subtype_inter _ _).symm,
  276. apply subtype_equiv_prop,
  277. tidy
  278. },
  279.  
  280. have hab' : a ≠ b,
  281. {
  282. rintro rfl,
  283. simp [everything_but] at hab,
  284. exact hab,
  285. },
  286.  
  287. refine subtype_equiv (perm_ignore_two_cycle a b) _,
  288. rintro ⟨f, hf⟩,
  289. exact perm_ignore_two_cycle_derangement_iff a b hab' f hf,
  290. end
  291.  
  292.  
  293. lemma special_2 (a : α) (b : everything_but a):
  294. {f : derangements α // f a = b ∧ f b ≠ a} ≃ derangements (everything_but a) :=
  295. begin
  296. cases b with b hab,
  297.  
  298. transitivity {f' : {f : perm α // f a = b} // f'.val b ≠ a ∧ is_derangement f'.val},
  299. {
  300. apply equiv.trans
  301. (subtype_subtype_equiv_subtype_inter _ (λ f : perm α, f a = b ∧ f b ≠ a))
  302. _,
  303. apply equiv.trans
  304. _
  305. (subtype_subtype_equiv_subtype_inter _ (λ f : perm α, f b ≠ a ∧ is_derangement f)).symm,
  306. apply subtype_equiv_prop,
  307. tidy,
  308. },
  309.  
  310. have hab' : a ≠ b,
  311. {
  312. rintro rfl,
  313. simp [everything_but] at hab,
  314. exact hab,
  315. },
  316.  
  317. refine subtype_equiv (perm_splice_out a b) _,
  318. rintro ⟨f, hf⟩,
  319. exact nice_splice_lemma a b hab' f hf,
  320. end
  321.  
  322.  
  323. lemma spicy_lemma (a : α) (b : everything_but a) :
  324. {f : derangements α // f a = b} ≃ (derangements (neither_of a b) ⊕ derangements (everything_but a)) :=
  325. begin
  326. -- split the type into those that send b back to a, and those that don't
  327. let b_goes_back_to_a : derangements α → Prop := λ f, f b = a,
  328.  
  329. refine equiv.trans (sum_compl (b_goes_back_to_a ∘ coe)).symm _,
  330. apply equiv.sum_congr,
  331. {
  332. exact (subtype_subtype_equiv_subtype_inter _ _).trans (special_1 a b),
  333. },
  334. {
  335. calc {f : {f : derangements α // f a = b} // ¬(b_goes_back_to_a ∘ coe) f }
  336. ≃ {f : derangements α // f a = b ∧ ¬b_goes_back_to_a f} : subtype_subtype_equiv_subtype_inter _ (not ∘ b_goes_back_to_a)
  337. ... ≃ derangements (everything_but a) : special_2 a b,
  338. },
  339. end
  340.  
  341. theorem derangements_recursion_equiv (a : α):
  342. derangements α ≃ Σ b : everything_but a, (derangements (neither_of a b) ⊕ derangements (everything_but a)) :=
  343. begin
  344. -- the fiber over b = a is empty
  345. have fact : ∀ (b : α), {f : derangements α // f a = b} → b ∈ everything_but a,
  346. {
  347. rintros b ⟨⟨f, f_derangement⟩, fa_eq_b⟩,
  348. rw ← fa_eq_b,
  349. exact f_derangement a
  350. },
  351.  
  352. calc derangements α
  353. ≃ Σ b : α, {f : derangements α // f a = b}
  354. : (sigma_preimage_equiv _).symm
  355. ... ≃ Σ b : everything_but a, {f : derangements α // f a = b}
  356. : (sigma_subtype_equiv_of_subset _ _ fact).symm
  357. ... ≃ Σ b : everything_but a, (derangements (neither_of a b) ⊕ derangements (everything_but a))
  358. : sigma_congr_right (spicy_lemma a),
  359. end
  360.  
  361. end recursion
  362.  
  363.  
  364.  
  365. section finite_instances
  366.  
  367. variables {α : Type*} [decidable_eq α] [fintype α]
  368.  
  369. instance : decidable_pred (@is_derangement α) :=
  370. begin
  371. intro f,
  372. apply fintype.decidable_forall_fintype,
  373. end
  374.  
  375. instance : fintype (derangements α) :=
  376. begin
  377. have : fintype (perm α) := by apply_instance,
  378. dsimp [derangements],
  379. exact set_fintype (set_of is_derangement),
  380. end
  381.  
  382. instance (a : α) : fintype (everything_but a) :=
  383. begin
  384. simp [everything_but],
  385. apply fintype.of_finset ({a}ᶜ : finset α),
  386. simp,
  387. end
  388.  
  389. instance (a : α) (b : everything_but a) : fintype (neither_of a b) :=
  390. begin
  391. simp [everything_but, neither_of],
  392. apply fintype.of_finset ({a, b}ᶜ : finset α),
  393. simp,
  394. end
  395.  
  396.  
  397. end finite_instances
  398.  
  399.  
  400.  
  401.  
  402. section counting
  403.  
  404. def num_derangements (n : ℕ) : ℕ := card (derangements (fin n))
  405.  
  406. lemma num_derangements_invariant (α : Type*) [fintype α] [decidable_eq α] :
  407. card (derangements α) = num_derangements (card α) :=
  408. begin
  409. unfold num_derangements,
  410. apply card_eq.mpr, -- eq because we don't need the specific equivalence
  411. -- TODO what's `trunc`? it's related to non-computability i think
  412. obtain ⟨e⟩ := equiv_fin α,
  413. use derangement_congr e,
  414. end
  415.  
  416. theorem num_derangements_recursive (n : ℕ) :
  417. num_derangements (n+2) = (n+1) * num_derangements n + (n+1) * num_derangements (n+1) :=
  418. begin
  419. let X := fin(n+2),
  420. let star : X := 0, -- could be any element tbh
  421.  
  422. have card_everything_but : card (everything_but star) = (n + 1),
  423. { simp [everything_but, finset.card_compl] },
  424.  
  425. have card_neither_of : ∀ m : everything_but star, card (neither_of star m) = n,
  426. {
  427. simp [everything_but, finset.card_compl],
  428. intros m hm,
  429.  
  430. suffices : finset.card ({star, m} : finset X) = 2,
  431. { simp [this] },
  432.  
  433. -- TODO this is very clunky, what tricks can i use here?
  434. rw finset.card_insert_of_not_mem,
  435. { simp },
  436. {
  437. change _ ≠ _ at hm,
  438. simp [hm.symm],
  439. }
  440. },
  441.  
  442. have card_der_1 : card (derangements (everything_but star)) = num_derangements (n+1),
  443. { rw [num_derangements_invariant, card_everything_but] },
  444.  
  445. have card_der_2 : ∀ m : everything_but star, card (derangements (neither_of star m)) = num_derangements n,
  446. {
  447. intro m,
  448. rw num_derangements_invariant,
  449. rw card_neither_of
  450. },
  451.  
  452. have key := card_congr (derangements_recursion_equiv star),
  453. rw num_derangements_invariant X at key,
  454. simp [card_der_1, card_der_2] at key,
  455.  
  456. -- TODO dunno why this didn't work out with simp, but whatever
  457. simp [fintype.card] at card_everything_but,
  458. rw [key, card_everything_but],
  459. ring,
  460. end
  461.  
  462. open_locale big_operators
  463.  
  464. theorem num_derangements_sum (n : ℕ) :
  465. (num_derangements n : ℚ) = n.factorial * ∑ k in finset.range (n + 1), (-1 : ℚ)^k / k.factorial :=
  466. begin
  467. refine nat.strong_induction_on n _,
  468. clear n, -- ???
  469.  
  470. intros n hyp,
  471.  
  472. -- need to knock out cases n = 0, 1
  473. cases n,
  474. { finish }, -- wow, what a tactic!
  475.  
  476. cases n,
  477. { finish },
  478.  
  479. -- now we have n ≥ 2
  480. rw num_derangements_recursive,
  481. push_cast,
  482.  
  483. -- TODO can these proofs be inferred from some tactic?
  484. rw hyp n (nat.lt_succ_of_le (nat.le_succ _)),
  485. rw hyp n.succ (lt_add_one _),
  486.  
  487. -- push all the constants inside the sums, strip off some trailing terms,
  488. -- and compare term-wise
  489. repeat { rw finset.mul_sum },
  490. conv_lhs {
  491. rw add_comm,
  492. congr,
  493. rw finset.sum_range_succ,
  494. },
  495. rw [add_assoc, ← finset.sum_add_distrib],
  496.  
  497. conv_rhs {
  498. rw finset.sum_range_succ,
  499. rw finset.sum_range_succ,
  500. rw ← add_assoc,
  501. },
  502.  
  503. congr,
  504. {
  505. -- delay factorial simplification until we're done clearing
  506. -- denominators
  507. field_simp [nat.factorial_ne_zero, -nat.factorial_succ, -nat.factorial],
  508. simp [nat.factorial_succ, pow_succ],
  509. ring,
  510. },
  511. {
  512. funext,
  513. field_simp [nat.factorial_ne_zero],
  514. ring,
  515. },
  516. end
  517.  
  518.  
  519. end counting
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement