Advertisement
Guest User

Untitled

a guest
Jul 7th, 2023
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 55.68 KB | None | 0 0
  1. (*****************************************************************************)
  2. (* Copyright 2022 TheWalker77 *)
  3. (* Permutations: Copyright 2017 IMDEA Software Institute *)
  4. (* *)
  5. (* Licensed under the Apache License, Version 2.0 (the "License"); *)
  6. (* you may not use this file except in compliance with the License. *)
  7. (* You may obtain a copy of the License at *)
  8. (* *)
  9. (* http://www.apache.org/licenses/LICENSE-2.0 *)
  10. (* *)
  11. (* Unless required by applicable law or agreed to in writing, software *)
  12. (* distributed under the License is distributed on an "AS IS" BASIS, *)
  13. (* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *)
  14. (* See the License for the specific language governing permissions and *)
  15. (* limitations under the License. *)
  16. (*****************************************************************************)
  17.  
  18. From mathcomp Require Export all_ssreflect zify.
  19. From mathcomp Require Export seq.
  20.  
  21. Set Implicit Arguments.
  22. Unset Strict Implicit.
  23. Import Prenex Implicits.
  24.  
  25. Lemma rcons_to_cat T (s: seq T) a: rcons s a = s ++ a::[::].
  26. Proof.
  27. elim: s => [//|a' s IH] /=.
  28. by rewrite IH.
  29. Qed.
  30.  
  31. Lemma map_cat_id T (s1 s2: seq T) f: map f (s1 ++ s2) = s1 ++ s2 ->
  32. map f s1 = s1 /\ map f s2 = s2.
  33. Proof.
  34. elim: s1 s2 => [|t s1 IHs1] s2 //=.
  35. by move => [-> /IHs1 [-> ->]].
  36. Qed.
  37.  
  38. Lemma size_zero_iff_nil {A} (s: seq A):
  39. size s = 0 <-> s = [::].
  40. Proof.
  41. by case :s.
  42. Qed.
  43. Lemma zip_emptyl {A B} (s: seq B): @zip A B [::] s = [::].
  44. Proof.
  45. by case: s.
  46. Qed.
  47.  
  48. Lemma zip_emptyr {A B} (s: seq A): @zip A B s [::] = [::].
  49. Proof.
  50. by case: s.
  51. Qed.
  52.  
  53. Lemma map_zip2 {A B C D} (s1: seq A) (s2: seq B) (f: A -> C) (g: B -> D):
  54. zip (map f s1) (map g s2) = map (fun xy => ((f (fst xy)), (g (snd xy)))) (zip s1 s2).
  55. Proof.
  56. elim: s2 s1 => [|b s2 IHs2];
  57. elim => [|a s1 IHs1] //=.
  58. by rewrite IHs2.
  59. Qed.
  60.  
  61. Lemma zip_rcons {A B} (a: A) (b: B) sa sb:
  62. size sa = size sb ->
  63. zip (rcons sa a) (rcons sb b) = rcons (zip sa sb) (a, b).
  64. Proof.
  65. elim: sa sb a b => [/=|a' sa IHsa] [|b' sb] a b //=.
  66. move => [Hsize].
  67. by rewrite IHsa.
  68. Qed.
  69.  
  70. (* propositional version of \in this one does not require eqTypev*)
  71. Inductive PIn {A}: A -> seq A -> Prop :=
  72. | pin_here (a : A) l : PIn a (a::l)
  73. | pin_future (a b : A) l : PIn a l -> PIn a (b::l).
  74.  
  75. Lemma inP (A: eqType): forall (a: A) (l: seq A), reflect (PIn a l) (a \in l).
  76. Proof.
  77. move => a l.
  78. apply: (iffP idP).
  79. - move: a.
  80. have ? := pin_here.
  81. elim : l => [|a' l Hind] //= a /[!in_cons].
  82. move /orP => [|a_in_l].
  83. by move /eqP ->.
  84. apply: pin_future.
  85. by apply: Hind.
  86. - move => HPIn.
  87. induction HPIn as [a l| a b l HInd].
  88. by apply: mem_head.
  89. rewrite in_cons.
  90. apply/orP.
  91. by right.
  92. Qed.
  93.  
  94. Lemma neg_inP (A: eqType): forall (a: A) (l: seq A),
  95. reflect (~ PIn a l) (a \notin l).
  96. Proof.
  97. move => a l.
  98. apply: (iffP idP).
  99. - move /negP => a_not_in_l a_PIn_l.
  100. apply: a_not_in_l.
  101. by apply/inP.
  102. - move => not_PIn_a_l.
  103. apply/negP => a_in_l.
  104. apply: not_PIn_a_l.
  105. by apply/inP.
  106. Qed.
  107.  
  108. Lemma PIn_cons_or A (a b: A) (l: seq A) : PIn a (b::l) <->
  109. a = b \/ PIn a l.
  110. Proof.
  111. split.
  112. move => HPIn.
  113. inversion HPIn; subst.
  114. by left.
  115. by right.
  116. move => [-> | HPIn].
  117. by apply: pin_here.
  118. by apply: pin_future.
  119. Qed.
  120.  
  121. Lemma not_PIn_cons_and A (a b: A) (l: seq A) : ~ PIn a (b::l) <->
  122. a <> b /\ ~ PIn a l.
  123. Proof.
  124. rewrite PIn_cons_or.
  125. split.
  126. move => Hnot.
  127. split;
  128. move => HFalse;
  129. apply: Hnot.
  130. by left.
  131. by right.
  132. by move => [Hneq HnotIn] [Heq | Hin].
  133. Qed.
  134.  
  135. Lemma PIn_empty_false A (a: A): ~ PIn a [::].
  136. Proof.
  137. move =>HFalse.
  138. inversion HFalse.
  139. Qed.
  140.  
  141. Lemma PIn_empty_false_iff A (a: A): PIn a [::] <-> False.
  142. Proof.
  143. split.
  144. by apply: PIn_empty_false.
  145. by [].
  146. Qed.
  147.  
  148. Lemma PIn_empty A (l: seq A) : l = [::] <-> forall a, ~PIn a l.
  149. Proof.
  150. split.
  151. move ->.
  152. by apply: PIn_empty_false.
  153. case : l => [|a l] Hnot_in.
  154. by [].
  155. have HFalse := (Hnot_in a).
  156. contradict HFalse.
  157. by apply: pin_here.
  158. Qed.
  159.  
  160. Lemma PIn_here_eq A (a b: A) (l: seq A): a = b -> PIn a (b::l).
  161. Proof.
  162. move ->.
  163. by apply: pin_here.
  164. Qed.
  165.  
  166. Lemma pin_map1 {A B } (b: B) (l : seq A) f:
  167. PIn b (map f l) -> exists a, b = f a /\ PIn a l.
  168. Proof.
  169. elim : l => [|a l IHl] /=.
  170. move => HFalse.
  171. by inversion HFalse.
  172. move /PIn_cons_or => [->|pin_l].
  173. exists a.
  174. split.
  175. by [].
  176. apply: pin_here.
  177. case : (IHl pin_l) => [a' [-> Hin]].
  178. exists a'.
  179. split.
  180. by [].
  181. by apply: pin_future.
  182. Qed.
  183.  
  184. Lemma pin_map2 {A B} (b: B) (l : seq A) f:
  185. (exists a, b = f a /\ PIn a l) -> PIn b (map f l).
  186. Proof.
  187. elim : l => [| a l IHl] /=;
  188. move => [a' []].
  189. by rewrite !PIn_empty_false_iff.
  190. move => Heq.
  191. move : Heq IHl => -> IHl.
  192. move /PIn_cons_or => [->|Hin].
  193. by apply: pin_here.
  194. apply: pin_future.
  195. apply: IHl.
  196. by exists a'.
  197. Qed.
  198.  
  199. Lemma pin_map {A B } (b: B) (l : seq A) f:
  200. PIn b (map f l) <-> exists a, b = f a /\ PIn a l.
  201. Proof.
  202. split.
  203. by apply: pin_map1.
  204. by apply: pin_map2.
  205. Qed.
  206.  
  207.  
  208. Lemma pin_seq_pin_fst A B (l: seq (A * B)) k v:
  209. PIn (k, v) l ->
  210. PIn k (map (fun kv => kv.1) l).
  211. Proof.
  212. elim : l => [| [k' v'] l IHl] /=.
  213. by rewrite !PIn_empty_false_iff.
  214. move /PIn_cons_or => [[<- Heq]| Hin].
  215. by apply: pin_here.
  216. apply: pin_future.
  217. by apply: IHl.
  218. Qed.
  219.  
  220. Lemma PIn_app A a (l1 l2: seq A) : PIn a (l1 ++ l2) <-> PIn a l1 \/ PIn a l2.
  221. Proof.
  222. elim : l1 => [|a' l1 IHl1] /=.
  223. split.
  224. by right.
  225. move => [HFalse | HIn];
  226. by [|have := PIn_empty_false HFalse].
  227. rewrite !PIn_cons_or IHl1.
  228. split.
  229. move => [->|[Hin|Hin]].
  230. - left.
  231. by left.
  232. - left.
  233. by right.
  234. - by right.
  235. move => [[->|Hin]|Hin].
  236. - by left.
  237. - right.
  238. by left.
  239. - right.
  240. by right.
  241. Qed.
  242.  
  243. Lemma PIn_singlton {A} (a b: A): a = b <-> PIn a [:: b].
  244. Proof.
  245. split.
  246. move ->.
  247. apply: pin_here.
  248. rewrite PIn_cons_or.
  249. move => [->|HFalse];
  250. by [| have := PIn_empty_false HFalse].
  251. Qed.
  252.  
  253. Lemma PIn_rev A a (l: seq A) : PIn a l <-> PIn a (rev l).
  254. Proof.
  255. elim : l => [|a' l IHl].
  256. by rewrite /rev /=.
  257. rewrite PIn_cons_or -cat1s.
  258. by rewrite rev_cat PIn_app -PIn_singlton IHl or_comm.
  259. Qed.
  260.  
  261. Lemma PIn_rcons_or A (a b: A) (l: seq A) : PIn a (rcons l b) <->
  262. a = b \/ PIn a l.
  263. Proof.
  264. rewrite PIn_rev rev_rcons PIn_cons_or.
  265. by rewrite -PIn_rev.
  266. Qed.
  267.  
  268. Lemma PIn_split1 A (a: A) l : PIn a l -> exists s1 s2, l = s1 ++ a :: s2.
  269. Proof.
  270. elim : l => [| a' l IHl].
  271. by rewrite PIn_empty_false_iff.
  272. rewrite PIn_cons_or.
  273. move => [<-| Hin].
  274. by exists [::], l.
  275. move : (IHl Hin) => [s1 [s2 Heq]].
  276. exists (a'::s1), s2.
  277. by rewrite Heq.
  278. Qed.
  279.  
  280. Lemma PIn_split2 A (a: A) l : (exists s1 s2, l = s1 ++ a :: s2) -> PIn a l.
  281. Proof.
  282. move => [s1 [s2 ->]].
  283. rewrite PIn_app.
  284. right.
  285. by apply: pin_here.
  286. Qed.
  287.  
  288. Lemma PIn_split A (a: A) l : PIn a l <-> exists s1 s2, l = s1 ++ a :: s2.
  289. Proof.
  290. split.
  291. by apply: PIn_split1.
  292. by apply: PIn_split2.
  293. Qed.
  294.  
  295. Lemma PIn_zip_id A (a b: A) l : PIn (a, b) (zip l l) <-> a = b /\ PIn a l.
  296. Proof.
  297. elim: l => [|a' l IHl] /=.
  298. rewrite !PIn_empty_false_iff.
  299. split => //.
  300. by move => [].
  301. rewrite !PIn_cons_or IHl.
  302. split.
  303. move => [[<- <-]|[<- ?]];
  304. split => //;
  305. by [left|right].
  306. move => [<-] [<-|?];
  307. by [left | right].
  308. Qed.
  309.  
  310. Lemma Pin_zip_flip A B (a: A) (b: B) la lb:
  311. PIn (a, b) (zip la lb) -> PIn (b, a) (zip lb la).
  312. Proof.
  313. elim: la lb a b => [|a' la IHla].
  314. move => ??? /=.
  315. by rewrite zip_emptyl PIn_empty_false_iff.
  316. move => [|b' lb] a b /=.
  317. by rewrite PIn_empty_false_iff.
  318. rewrite !PIn_cons_or.
  319. move => [[-> ->]|Hin].
  320. by left.
  321. right.
  322. by apply: IHla.
  323. Qed.
  324.  
  325. Lemma Pin_zip_flip_iff A B (a: A) (b: B) la lb:
  326. PIn (a, b) (zip la lb) <-> PIn (b, a) (zip lb la).
  327. Proof.
  328. split;
  329. by apply: Pin_zip_flip.
  330. Qed.
  331.  
  332. Lemma seq_map_ext {A B } (l : seq A) (f g: A -> B):
  333. (forall x, PIn x l -> f x = g x) ->
  334. map f l = map g l.
  335. Proof.
  336. elim: l => [//|a l IHl] Hext /=.
  337. rewrite Hext;
  338. last by apply: pin_here.
  339. rewrite IHl //.
  340. move => x Hin.
  341. apply: Hext.
  342. by apply: pin_future.
  343. Qed.
  344.  
  345. (* propositional version of Uniq and it does not require eqType *)
  346. Inductive PUniq {A} : seq A -> Prop :=
  347. | puniq_nil : PUniq [::]
  348. | puniq_cons (a: A) l: ~ PIn a l -> PUniq l -> PUniq (a::l).
  349.  
  350. Lemma uniqP (A: eqType): forall (l: seq A), reflect (PUniq l) (uniq l).
  351. Proof.
  352. move => l.
  353. apply: (iffP idP).
  354. - have ? := puniq_nil.
  355. elim : l => [|a l Hind] //=.
  356. move /andP => [a_not_in_l uniq_l].
  357. apply: puniq_cons.
  358. by apply/neg_inP.
  359. by apply: Hind.
  360. - move => HPuniq.
  361. induction HPuniq as [|a l a_not_in_l Hind] => //=.
  362. apply/andP.
  363. split => //=.
  364. by apply/neg_inP.
  365. Qed.
  366.  
  367. Lemma uniq_inv A a (l: seq A):
  368. PUniq (a :: l) <-> ~ PIn a l /\ PUniq l.
  369. Proof.
  370. split.
  371. move => Huniq.
  372. by inversion Huniq; subst.
  373. move => [Hnot_in Huniq].
  374. by apply: puniq_cons.
  375. Qed.
  376.  
  377. Lemma puniq_app1 A (s1 s2: seq A):
  378. PUniq (s1 ++ s2) ->
  379. PUniq s1 /\ PUniq s2 /\ (forall x, PIn x s1 -> PIn x s2 -> False).
  380. Proof.
  381. elim : s1 s2 => [|a s1 IHs1] s2 /=.
  382. move => Huniq2.
  383. split.
  384. by apply: puniq_nil.
  385. split.
  386. by [].
  387. move => x.
  388. by rewrite PIn_empty_false_iff.
  389. rewrite !uniq_inv PIn_app.
  390. move => [ Hnotin12 Huniq12].
  391. move : (IHs1 _ Huniq12) => [Huniq1 [Huniq2 Hnotinin]].
  392. split.
  393. split;
  394. last by [].
  395. move => Hina.
  396. apply Hnotin12.
  397. by left.
  398. split.
  399. by [].
  400. move => x.
  401. rewrite PIn_cons_or.
  402. move => [->|Hina1] Hina2.
  403. apply: Hnotin12.
  404. by right.
  405. by apply: (Hnotinin x).
  406. Qed.
  407.  
  408. Lemma puniq_app2 A (s1 s2: seq A):
  409. PUniq s1 ->
  410. PUniq s2 ->
  411. (forall x, PIn x s1 -> PIn x s2 -> False) ->
  412. PUniq (s1 ++ s2).
  413. Proof.
  414. elim : s1 s2 => [|a s1 IHs1] s2 /=.
  415. by [].
  416. rewrite !uniq_inv.
  417. move => [Hnotin1 Huniq1] Huni2 Hnotinin.
  418. split.
  419. move /PIn_app => [Hin1|Hin2].
  420. by [].
  421. apply: (Hnotinin a).
  422. by apply: pin_here.
  423. by [].
  424. apply: IHs1 => //=.
  425. move => x Hin1 Hin2.
  426. apply: (Hnotinin x);
  427. last by [].
  428. rewrite PIn_cons_or.
  429. by right.
  430. Qed.
  431.  
  432. Lemma puniq_app A (s1 s2: seq A):
  433. PUniq (s1 ++ s2) <->
  434. PUniq s1 /\ PUniq s2 /\ (forall x, PIn x s1 -> PIn x s2 -> False).
  435. Proof.
  436. split.
  437. by apply: puniq_app1.
  438. move => [?[]].
  439. by apply: puniq_app2.
  440. Qed.
  441.  
  442. Lemma puniq_map_inv_fun A B (l: seq A) (f: A -> B):
  443. (forall a b, PIn a l -> PIn b l -> f a = f b -> a = b) ->
  444. PUniq l -> PUniq (map f l).
  445. Proof.
  446. elim: l => [|a l IHl] /= Hinv.
  447. move => _.
  448. by apply: puniq_nil.
  449. rewrite !uniq_inv.
  450. move => [Hnotin Huniq].
  451. split;
  452. last first.
  453. apply: IHl => // a' b' PIn Heq.
  454. apply: Hinv => //;
  455. by apply pin_future => //.
  456. move /pin_map => [a' [Hfeq Hin]].
  457. apply: Hnotin.
  458. have := Hinv _ _ _ _ Hfeq.
  459. move => -> //.
  460. - by apply pin_here.
  461. - by apply: pin_future.
  462. Qed.
  463.  
  464. Lemma puniq_map_inv_fun_weak A B (l: seq A) (f: A -> B):
  465. (forall a b, f a = f b -> a = b) ->
  466. PUniq l -> PUniq (map f l).
  467. Proof.
  468. move => Hinj.
  469. apply: puniq_map_inv_fun => a b Hina Hinb.
  470. by apply: Hinj.
  471. Qed.
  472.  
  473.  
  474. (* properties of associated seqs *)
  475. Lemma uniq_map_fst A B (l: seq (A * B)):
  476. (forall k v1 v2, PIn (k, v1) l -> PIn (k, v2) l -> v1 = v2) ->
  477. PUniq l -> PUniq (map (fun kv => kv.1) l).
  478. Proof.
  479. elim : l => [|[k v] l IHl] /= Hext Huniql /=.
  480. by apply: puniq_nil.
  481. apply: puniq_cons;
  482. last first.
  483. apply: IHl;
  484. last by inversion Huniql.
  485. move => k' v1 v2 Hin1 Hin2.
  486. apply: (Hext k');
  487. by apply: pin_future.
  488. move /pin_map => [[a b]] /= [] <- Hin.
  489. inversion Huniql; subst.
  490. have Hin_future: PIn (k,b) ((k, v)::l).
  491. by apply: pin_future.
  492. have Hinkvl: PIn (k, v) ((k, v):: l).
  493. by apply: pin_here.
  494. have Heq := Hext k b v Hin_future Hinkvl.
  495. apply: H1.
  496. by rewrite -Heq.
  497. Qed.
  498.  
  499.  
  500. Lemma uniq_map_in_in {A B} (l: seq (A * B)) k v1 v2:
  501. PUniq (map (fun kv => kv.1) l) ->
  502. PIn (k, v1) l ->
  503. PIn (k, v2) l ->
  504. v1 = v2.
  505. Proof.
  506. elim : l => [| [k' v'] l IHl] /=;
  507. rewrite ?PIn_empty_false_iff => Huniq Hinv1 Hinv2.
  508. by [].
  509. move : Huniq.
  510. move /uniq_inv => [Hnot_in Huniq].
  511. move : Hinv1 Hinv2 Hnot_in IHl.
  512. move /PIn_cons_or => [[<- <-]| Hin_v1];
  513. move /PIn_cons_or => [|].
  514. - by move => [<-].
  515. - move => Hin_v2 Hnot_in.
  516. by have := pin_seq_pin_fst Hin_v2.
  517. - move => [<- ->] Hnot_in IHl.
  518. by have := pin_seq_pin_fst Hin_v1.
  519. - move => Hinv2 Hnot_in IHl.
  520. by apply: IHl.
  521. Qed.
  522.  
  523. Definition seq_forall {A} (P: A -> Prop) (s: seq A) :=
  524. foldl (fun p a => P a /\ p ) True s.
  525.  
  526. Fixpoint seq_forall2 {A} (P: A -> Prop) (s: seq A) :=
  527. match s with
  528. | [::] => True
  529. | a::s' => P a /\ seq_forall2 P s'
  530. end.
  531.  
  532. Lemma all_seq_forall {A} P (s: seq A): all P s <-> seq_forall2 P s.
  533. Proof.
  534. elim: s => [//|a s IHs] /=.
  535. rewrite -IHs.
  536. split.
  537. by move/andP.
  538. by move => [-> ->].
  539. Qed.
  540.  
  541. Lemma seq_forall_forall {A} (P: A -> Prop) (s: seq A) :
  542. seq_forall P s <-> (forall a, PIn a s -> P a).
  543. Proof.
  544. rewrite /seq_forall.
  545. elim/last_ind: s => [|l a IHl].
  546. split => //.
  547. move => _ a.
  548. by rewrite PIn_empty_false_iff.
  549. rewrite foldl_rcons IHl.
  550. split.
  551. move => [HP HIn] a'.
  552. move /PIn_rcons_or => [->|].
  553. by [].
  554. by apply: HIn.
  555. move => HIn.
  556. split.
  557. apply: HIn.
  558. apply/PIn_rcons_or.
  559. by left.
  560. move => a' HInl.
  561. apply: HIn.
  562. apply/PIn_rcons_or.
  563. by right.
  564. Qed.
  565.  
  566. Lemma seq_forall2_forall {A} (P: A -> Prop) (s: seq A) :
  567. seq_forall2 P s <-> (forall a, PIn a s -> P a).
  568. Proof.
  569. elim: s => [|a l IHl] /=.
  570. split => [_ a|//].
  571. by rewrite PIn_empty_false_iff.
  572. split => [[Hp Hall] a'|].
  573. rewrite PIn_cons_or.
  574. move => [->//|].
  575. by apply IHl.
  576. move => Hall.
  577. split.
  578. apply Hall.
  579. rewrite PIn_cons_or.
  580. by left.
  581. rewrite IHl => a' Hin.
  582. apply Hall.
  583. rewrite PIn_cons_or.
  584. by right.
  585. Qed.
  586.  
  587. Lemma seq_forall_seq_forall2 {A} (P: A -> Prop) (s: seq A) :
  588. seq_forall2 P s <-> seq_forall P s.
  589. Proof.
  590. by rewrite seq_forall2_forall seq_forall_forall.
  591. Qed.
  592.  
  593. Lemma seq_forall_empty {A} (P: A -> Prop):
  594. seq_forall P [::] <-> True.
  595. Proof.
  596. rewrite seq_forall_forall.
  597. split => [//|??].
  598. by rewrite PIn_empty_false_iff.
  599. Qed.
  600.  
  601. Definition seq_exists {A} (P: A -> Prop) (s: seq A) :=
  602. foldl (fun p a => P a \/ p ) False s.
  603.  
  604. Lemma seq_exists_exists {A} (P: A -> Prop) (s: seq A) :
  605. seq_exists P s <-> exists a, PIn a s /\ P a.
  606. Proof.
  607. rewrite /seq_exists.
  608. elim/last_ind: s => [|s a IHs].
  609. split => //.
  610. move => [a []].
  611. by rewrite PIn_empty_false_iff.
  612. rewrite foldl_rcons IHs.
  613. split.
  614. move => [HP|[a' [HIn HP]]];
  615. (exists a' || exists a);
  616. rewrite PIn_rcons_or;
  617. split => //;
  618. by [left | right].
  619. move => [a'].
  620. rewrite PIn_rcons_or.
  621. move => [[->| Hin]] HP.
  622. by left.
  623. right.
  624. by exists a'.
  625. Qed.
  626.  
  627. (* A theory of indexed mapping *)
  628. (* This section is based on MetaCoq "utils/theories/MCList.v" commit ID: *)
  629. (* 82571676cbe51c0eb76806553e55c2b7bd2e34c8 which is licensed under MIT as *)
  630. (* follows: *)
  631. (* Copyright (c) 2014-2018 Gregory Malecha *)
  632. (* Copyright (c) 2015-2018 Abhishek Anand, Matthieu Sozeau *)
  633. (* Copyright (c) 2017-2018 Simon Boulier, Nicolas Tabareau, Cyril Cohen *)
  634. (* Copyright (c) 2018-2020 Danil Annenkov, Yannick Forster, Théo Winterhalter *)
  635.  
  636. Section IMAP.
  637. Variable A B: Type.
  638. Variable f: nat -> A -> B.
  639.  
  640. Fixpoint imap_rec (l : seq A) (n : nat) : seq B :=
  641. match l with
  642. | [::] => [::]
  643. | hd :: tl => f n hd :: imap_rec tl n.+1
  644. end.
  645.  
  646. Definition imap (l : seq A) := imap_rec l 0.
  647. End IMAP.
  648.  
  649. Section MapIndexRev.
  650. Variable T U: Type.
  651. Variable f: nat -> T -> U.
  652. Definition rimap (s: seq T) :=
  653. imap (fun n => f (size s - n.+1)) s.
  654. End MapIndexRev.
  655.  
  656. Section IMAP1.
  657. Variable A B C: Type.
  658. Variable f g: nat -> A -> B.
  659. Variable h: nat -> B -> C.
  660.  
  661. Lemma imap_rec_id T (l: seq T) n:
  662. imap_rec (fun _ => id) l n = l.
  663. Proof.
  664. elim : l n => [//|a l IHl] n /=.
  665. by rewrite IHl.
  666. Qed.
  667.  
  668. Lemma imap_id T (l: seq T):
  669. imap (fun _ => id) l = l.
  670. Proof.
  671. by rewrite /imap imap_rec_id.
  672. Qed.
  673.  
  674. Lemma imap_rec_ext_size l k :
  675. (forall k' x, PIn x l -> k' < k + size l -> f k' x = g k' x) ->
  676. imap_rec f l k = imap_rec g l k.
  677. Proof.
  678. move => Hext.
  679. have: k <= k.
  680. by lia.
  681. generalize k at 1 3 4.
  682. elim: l k Hext => [//|a l IHl] k Hext /=.
  683. move => k' Hle.
  684. rewrite Hext /=;
  685. last first.
  686. - by lia.
  687. - by apply pin_here.
  688. rewrite (IHl k.+1) //.
  689. move => k'' x Hin Hlt.
  690. apply:Hext => /=.
  691. by apply: pin_future.
  692. by lia.
  693. Qed.
  694.  
  695. Lemma imap_ext_size l :
  696. (forall k x, PIn x l -> k < size l -> f k x = g k x) ->
  697. imap f l = imap g l.
  698. Proof.
  699. move => Hext.
  700. by apply: imap_rec_ext_size.
  701. Qed.
  702.  
  703. Lemma imap_rec_ext_size2 l k :
  704. (forall x l1 l2, l = l1 ++ x::l2 -> f (k + size l1) x = g (k + size l1) x) ->
  705. imap_rec f l k = imap_rec g l k.
  706. Proof.
  707. elim: l k => [//|a l IHl] k Hext /=.
  708. f_equal.
  709. have := Hext a [::] l => /=.
  710. rewrite addn0 => Heq.
  711. by apply: Heq.
  712. apply: IHl => x l1 l2 Heq.
  713. have := Hext x (a::l1) l2 => /=.
  714. rewrite -Heq addSnnS => Hext'.
  715. by apply: Hext'.
  716. Qed.
  717.  
  718. Lemma imap_ext_size2 l:
  719. (forall x l1 l2, l = l1 ++ x::l2 -> f (size l1) x = g (size l1) x) ->
  720. imap f l = imap g l.
  721. Proof.
  722. move => Hext.
  723. by rewrite /imap imap_rec_ext_size2.
  724. Qed.
  725.  
  726. Lemma imap_rec_compose k l :
  727. imap_rec h (imap_rec f l k) k = imap_rec (fun k x => h k (f k x)) l k.
  728. Proof.
  729. elim: l k => [//|a l IHl] k/=.
  730. by rewrite IHl.
  731. Qed.
  732.  
  733. Lemma imap_compose l : imap h (imap f l) = imap (fun k x => h k (f k x)) l.
  734. Proof.
  735. by apply imap_rec_compose.
  736. Qed.
  737.  
  738. Lemma imap_rec_eqn l a n :
  739. imap_rec f (a :: l) n = f n a :: imap_rec f l (S n).
  740. Proof.
  741. by [].
  742. Qed.
  743.  
  744. Lemma imap_map (l : seq A) (f' : A -> B) :
  745. imap h (map f' l) = imap (fun i x => h i (f' x)) l.
  746. Proof.
  747. rewrite /imap.
  748. move: 0.
  749. elim :l => [//|a l IHl] n /=.
  750. by rewrite IHl.
  751. Qed.
  752.  
  753. Lemma map_imap (l : seq A) (g' : B -> C) :
  754. map g' (imap f l) = imap (fun i x => g' (f i x)) l.
  755. Proof.
  756. rewrite /imap.
  757. move : 0.
  758. elim :l => [//|a l IHl] n /=.
  759. by rewrite IHl.
  760. Qed.
  761.  
  762. Lemma imap_imap l :
  763. imap h (imap f l) = imap (fun n x => h n (f n x)) l.
  764. Proof.
  765. rewrite /imap.
  766. move: 0.
  767. elim :l => [//|a l IHl] n /=.
  768. by rewrite IHl.
  769. Qed.
  770.  
  771. Lemma imap_cst_map (f' : A -> B) l :
  772. imap (fun _ => f') l = map f' l.
  773. Proof.
  774. rewrite /imap.
  775. move: 0.
  776. elim: l => [//|a l IHl] n /=.
  777. by rewrite IHl.
  778. Qed.
  779.  
  780. Lemma imap_rec_ext (l : seq A) n :
  781. (forall k x, n <= k -> k < size l + n -> f k x = g k x) ->
  782. imap_rec f l n = imap_rec g l n.
  783. Proof.
  784. elim: l n => [//|a l IHl] n Hext /=.
  785. rewrite IHl.
  786. rewrite Hext //=.
  787. by lia.
  788. move => ????.
  789. apply: Hext => /=;
  790. by lia.
  791. Qed.
  792.  
  793. Lemma imap_ext l : (forall n x, f n x = g n x) -> imap f l = imap g l.
  794. Proof.
  795. move => ?.
  796. by apply: imap_rec_ext.
  797. Qed.
  798.  
  799. Lemma imap_rec_Sk l k : imap_rec f l (S k) = imap_rec (fun n x => f (S n) x) l k.
  800. Proof.
  801. elim: l k => [//|a l IHl] k /=.
  802. by rewrite IHl.
  803. Qed.
  804. End IMAP1.
  805.  
  806. Section IMAP2.
  807. Variable A B C: Type.
  808. Variable f g: nat -> A -> B.
  809. Variable h: nat -> B -> C.
  810.  
  811. Lemma imap_rec_add l n k:
  812. imap_rec f l (n + k) = imap_rec (fun (k : nat) (x : A) => f (n + k) x) l k.
  813. Proof.
  814. elim: l n k => [//|a l IHl n k] /=.
  815. have : (n + k).+1 = n.+1 + k.
  816. by lia.
  817. move ->.
  818. rewrite IHl imap_rec_Sk.
  819. erewrite imap_rec_ext => // ???? /=.
  820. f_equal.
  821. by lia.
  822. Qed.
  823.  
  824. Lemma imap_rec_app (l l' : seq A) n :
  825. (imap_rec f (l ++ l') n = imap_rec f l n ++ imap_rec f l' (size l + n)).
  826. Proof.
  827. elim: l n=> [//| a l IHl] n /=.
  828. rewrite IHl /=.
  829. f_equal.
  830. f_equal.
  831. f_equal.
  832. by lia.
  833. Qed.
  834.  
  835. Lemma imap_rec_n n m l:
  836. imap_rec f l (m + n) =
  837. imap_rec (fun n0 : nat => [eta f (m + n0)]) l n.
  838. Proof.
  839. elim: l m n => [//|a l IHl] m n /=.
  840. have : (m + n).+1 = m + n.+1.
  841. by lia.
  842. move => ->.
  843. by rewrite IHl.
  844. Qed.
  845.  
  846. Lemma imap_app (l l' : seq A) :
  847. (imap f (l ++ l') =
  848. imap f l ++ imap (fun n x => f (size l + n) x) l').
  849. Proof.
  850. rewrite /imap.
  851. by rewrite imap_rec_app imap_rec_n.
  852. Qed.
  853. End IMAP2.
  854.  
  855.  
  856. Section IMAP3.
  857. Variable A B C: Type.
  858. Variable f g: nat -> A -> B.
  859. Variable h: nat -> B -> C.
  860.  
  861. Lemma rev_imap_rec (l : seq A) n k:
  862. k <= n ->
  863. rev (imap_rec f l (n - k)) =
  864. imap_rec (fun k x => f ((size l).-1 + n - k) x) (rev l) k.
  865. Proof.
  866. rewrite /imap.
  867. elim/last_ind : l n k => [//|l x IHl] n k Hlt /=.
  868. rewrite rev_rcons.
  869. rewrite rcons_to_cat imap_rec_app.
  870. rewrite rev_cat IHl //=.
  871. rewrite size_cat addn1 /=.
  872. f_equal.
  873. f_equal.
  874. by lia.
  875. rewrite imap_rec_Sk.
  876. apply: imap_rec_ext.
  877. rewrite size_rev => ????.
  878. f_equal.
  879. by lia.
  880. Qed.
  881.  
  882. Lemma rev_imap (l : seq A) :
  883. rev (imap f l) = imap (fun k x => f ((size l).-1 - k) x) (rev l).
  884. Proof.
  885. rewrite /imap.
  886. change 0 with (0 - 0) at 1.
  887. by rewrite rev_imap_rec // addn0.
  888. Qed.
  889.  
  890. Lemma imap_rec_rev (l : seq A) n :
  891. imap_rec f (rev l) n = rev (imap (fun k x => f (size l + n - S k) x) l).
  892. Proof.
  893. rewrite /imap.
  894. elim/last_ind: l n => [//|a l IHl] n /=.
  895. rewrite rev_rcons /= IHl.
  896. rewrite rcons_to_cat imap_rec_app /=.
  897. rewrite rev_cat /=.
  898. rewrite size_cat /= addn1 addn0.
  899. have : (size a).+1 + n - (size a).+1 = n.
  900. by lia.
  901. move => ->.
  902. erewrite imap_rec_ext => //.
  903. move => ???? /=.
  904. f_equal.
  905. by lia.
  906. Qed.
  907.  
  908. Lemma imap_rev (l : seq A) :
  909. imap f (rev l) = rev (imap (fun k x => f (size l - S k) x) l).
  910. Proof.
  911. by rewrite /imap imap_rec_rev addn0.
  912. Qed.
  913.  
  914. Lemma imap_rec_size (l : seq A) n : size (imap_rec f l n) = size l.
  915. Proof.
  916. elim: l n => [//| a l IHl] n /=.
  917. by rewrite IHl.
  918. Qed.
  919.  
  920. Lemma imap_size (l : seq A) : size (imap f l) = size l.
  921. Proof.
  922. by apply: imap_rec_size.
  923. Qed.
  924.  
  925. Lemma imap_cons a l : imap f (a :: l) = f 0 a :: imap (fun x => f (S x)) l.
  926. Proof.
  927. by rewrite /imap /= imap_rec_Sk.
  928. Qed.
  929.  
  930. Lemma imap_nth (l : seq A) (l' : seq B) (default : A) : size l = size l' ->
  931. imap (fun i _ => nth default l i ) l' = l.
  932. Proof.
  933. rewrite /imap.
  934. elim: l' l => [//|a' l' IHl'] [|a l] //= [Heq].
  935. by rewrite imap_rec_Sk IHl'.
  936. Qed.
  937.  
  938. Lemma pin_imap_rec1 (l: seq A) b n:
  939. PIn b (imap_rec f l n) ->
  940. exists a l1 l2, l = l1 ++ a :: l2 /\ b = f (size l1 + n) a.
  941. Proof.
  942. move Heq :(imap_rec f l n) => l' Hin.
  943. elim: Hin l n Heq => {l'} [a0 l'|a0 a1 l' Hin IH] [//|a2 l] n /= [].
  944. move <- => Heql'.
  945. by exists a2, [::], l => /=.
  946. move => Heqa' Heql'.
  947. have := IH _ _ Heql'.
  948. move => [a3] [l1] [l2] [-> ->].
  949. exists a3, (a2::l1), l2.
  950. split => //=.
  951. f_equal.
  952. by lia.
  953. Qed.
  954.  
  955. Lemma pin_imap_rec2 (l: seq A) b n:
  956. (exists a l1 l2, l = l1 ++ a :: l2 /\ b = f (size l1 + n) a) ->
  957. PIn b (imap_rec f l n).
  958. Proof.
  959. move => [a] [l1] [l2] [-> ->].
  960. rewrite imap_rec_app PIn_app /=.
  961. right.
  962. by apply: pin_here.
  963. Qed.
  964.  
  965. Lemma pin_imap_rec (l: seq A) b n:
  966. PIn b (imap_rec f l n) <->
  967. exists a l1 l2, l = l1 ++ a :: l2 /\ b = f (size l1 + n) a.
  968. Proof.
  969. split.
  970. by apply: pin_imap_rec1.
  971. by apply: pin_imap_rec2.
  972. Qed.
  973.  
  974. Lemma pin_imap (l: seq A) b:
  975. PIn b (imap f l) <->
  976. exists a l1 l2, l = l1 ++ a :: l2 /\ b = f (size l1) a.
  977. Proof.
  978. rewrite /imap pin_imap_rec.
  979. split;
  980. move => [a] [l1] [l2] [-> ->];
  981. exists a, l1, l2;
  982. by rewrite addn0.
  983. Qed.
  984. End IMAP3.
  985.  
  986. Lemma imap_rec_zip {A B C D} (s1: seq A) (s2: seq B) (f: nat -> A -> C) (g: nat -> B -> D) n:
  987. zip (imap_rec f s1 n) (imap_rec g s2 n) = imap_rec (fun i xy => ((f i (fst xy)), (g i (snd xy)))) (zip s1 s2) n.
  988. Proof.
  989. elim: s2 s1 n => [|b s2 IHs2];
  990. elim => [|a s1 IHs1] n //=.
  991. by rewrite IHs2.
  992. Qed.
  993.  
  994. Lemma imap_zip {A B C D} (s1: seq A) (s2: seq B) (f: nat -> A -> C) (g: nat -> B -> D):
  995. zip (imap f s1) (imap g s2) = imap (fun i xy => ((f i (fst xy)), (g i (snd xy)))) (zip s1 s2).
  996. Proof.
  997. by rewrite /imap imap_rec_zip.
  998. Qed.
  999.  
  1000. Lemma imap_rec_cat_id T f (l l': seq T) n:
  1001. imap_rec f (l ++ l') n = l ++ l' ->
  1002. imap_rec f l n = l /\ imap_rec f l' (size l + n) = l'.
  1003. Proof.
  1004. elim: l l' n => [|t l IHl] l' n//=.
  1005. move => [-> /IHl [-> Heq]].
  1006. split => //.
  1007. rewrite -[in RHS]Heq.
  1008. f_equal.
  1009. by lia.
  1010. Qed.
  1011.  
  1012. Lemma imap_cat_id T f (l l': seq T):
  1013. imap f (l ++ l') = l ++ l' ->
  1014. imap f l = l /\ imap (fun n x => f (size l + n) x) l' = l'.
  1015. Proof.
  1016. rewrite /imap.
  1017. move/imap_rec_cat_id.
  1018. by rewrite imap_rec_n.
  1019. Qed.
  1020.  
  1021. Section RIMAP.
  1022. Variable A B C: Type.
  1023. Variable f g: nat -> A -> B.
  1024. Variable h: nat -> B -> C.
  1025.  
  1026. Lemma rimap_id T (l: seq T):
  1027. rimap (fun _ => id) l = l.
  1028. Proof.
  1029. by rewrite /rimap imap_id.
  1030. Qed.
  1031.  
  1032. Lemma rimap_ext_size l :
  1033. (forall k x, PIn x l -> k < size l -> f k x = g k x) ->
  1034. rimap f l = rimap g l.
  1035. Proof.
  1036. rewrite /rimap.
  1037. move => Hext.
  1038. apply: imap_ext_size => k x Hin Hlt.
  1039. apply: Hext => //.
  1040. by lia.
  1041. Qed.
  1042.  
  1043. Lemma rimap_ext_size2 l:
  1044. (forall x l1 l2, l = l1 ++ x::l2 -> f (size l2) x = g (size l2) x) ->
  1045. rimap f l = rimap g l.
  1046. Proof.
  1047. move => Hext.
  1048. rewrite /imap.
  1049. apply: imap_rec_ext_size2.
  1050. move => x l1 l2 Heq.
  1051. rewrite Heq size_cat /= add0n.
  1052. replace (size l1 + (size l2).+1 - (size l1).+1) with (size l2) by lia.
  1053. apply: Hext.
  1054. apply: Heq.
  1055. Qed.
  1056.  
  1057. Lemma rimap_compose l : rimap h (rimap f l) = rimap (fun k x => h k (f k x)) l.
  1058. Proof.
  1059. rewrite /rimap.
  1060. by rewrite imap_compose imap_size.
  1061. Qed.
  1062.  
  1063. Lemma rimap_map (l : seq A) (f' : A -> B) :
  1064. rimap h (map f' l) = rimap (fun i x => h i (f' x)) l.
  1065. Proof.
  1066. by rewrite /rimap imap_map size_map.
  1067. Qed.
  1068.  
  1069. Lemma map_rimap (l : seq A) (g' : B -> C) :
  1070. map g' (rimap f l) = rimap (fun i x => g' (f i x)) l.
  1071. Proof.
  1072. by rewrite /rimap map_imap.
  1073. Qed.
  1074.  
  1075. Lemma rimap_rimap l :
  1076. rimap h (rimap f l) = rimap (fun n x => h n (f n x)) l.
  1077. Proof.
  1078. by rewrite /rimap imap_imap imap_size.
  1079. Qed.
  1080.  
  1081. Lemma rimap_cst_map (f' : A -> B) l :
  1082. rimap (fun _ => f') l = map f' l.
  1083. Proof.
  1084. by rewrite /rimap imap_cst_map.
  1085. Qed.
  1086.  
  1087. Lemma rimap_ext l : (forall n x, f n x = g n x) -> rimap f l = rimap g l.
  1088. Proof.
  1089. move => ?.
  1090. by apply: imap_ext.
  1091. Qed.
  1092.  
  1093. Lemma rimap_app (l l' : seq A) :
  1094. (rimap f (l ++ l') =
  1095. rimap (fun n x => f (size l' + n) x) l ++ rimap f l').
  1096. Proof.
  1097. rewrite /rimap imap_app.
  1098. rewrite size_cat.
  1099. f_equal;
  1100. eapply imap_rec_ext => k x _;
  1101. rewrite addn0 => Hlt;
  1102. f_equal;
  1103. by lia.
  1104. Qed.
  1105.  
  1106. Lemma rev_rimap_imap (l : seq A) :
  1107. rev (rimap f l) = imap f (rev l).
  1108. Proof.
  1109. rewrite /rimap rev_imap.
  1110. apply: imap_ext_size => k x Hin.
  1111. rewrite size_rev => Hlt.
  1112. f_equal.
  1113. by lia.
  1114. Qed.
  1115.  
  1116. Lemma rimap_size (l : seq A) : size (rimap f l) = size l.
  1117. Proof.
  1118. by rewrite /rimap imap_size.
  1119. Qed.
  1120.  
  1121. Lemma rimap_cons a l : rimap f (a :: l) = f (size l) a :: rimap f l.
  1122. Proof.
  1123. rewrite /rimap.
  1124. rewrite imap_cons /=.
  1125. repeat f_equal.
  1126. by lia.
  1127. Qed.
  1128.  
  1129. Lemma pin_rimap (l: seq A) b:
  1130. PIn b (rimap f l) <->
  1131. exists a l1 l2, l = l1 ++ a :: l2 /\ b = f (size l2) a.
  1132. Proof.
  1133. rewrite /rimap pin_imap.
  1134. split;
  1135. move => [a] [l1] [l2] [-> ->];
  1136. exists a, l1, l2;
  1137. rewrite size_cat /=;
  1138. split => //;
  1139. f_equal;
  1140. by lia.
  1141. Qed.
  1142. End RIMAP.
  1143.  
  1144. Lemma rimap_cat_id T f (l l': seq T):
  1145. rimap f (l ++ l') = l ++ l' ->
  1146. rimap (fun n x => f (size l' + n) x) l = l /\ rimap f l' = l'.
  1147. Proof.
  1148. Proof.
  1149. rewrite /rimap size_cat.
  1150. move /imap_cat_id => [Heql Heql'].
  1151. split.
  1152. rewrite -[in RHS]Heql.
  1153. apply: imap_ext_size => k x Hin Hlt.
  1154. f_equal.
  1155. by lia.
  1156. rewrite -[in RHS]Heql'.
  1157. apply: imap_ext_size => k x Hin Hlt.
  1158. f_equal.
  1159. by lia.
  1160. Qed.
  1161.  
  1162. Lemma rimap_zip {A B C D} (s1: seq A) (s2: seq B) (f: nat -> A -> C) (g: nat -> B -> D):
  1163. size s1 = size s2 ->
  1164. zip (rimap f s1) (rimap g s2) = rimap (fun i xy => ((f i (fst xy)), (g i (snd xy)))) (zip s1 s2).
  1165. Proof.
  1166. move => Heq.
  1167. rewrite /rimap imap_zip.
  1168. rewrite size_zip Heq.
  1169. by rewrite minnn.
  1170. Qed.
  1171.  
  1172. (* This section is based on: *)
  1173. (* https://github.com/imdea-software/fcsl-pcm/blob/master/core/seqperm.v *)
  1174. (* commit id: 79bb8b3eae4d6c682a757b0c26f282ce378dab52 *)
  1175.  
  1176. (****************************************************)
  1177. (* A theory of permutations over non-equality types *)
  1178. (****************************************************)
  1179.  
  1180. Reserved Infix "≡ₚ" (at level 70, no associativity).
  1181. Inductive perm {A} : seq A -> seq A -> Prop :=
  1182. | permutation_nil : [::] ≡ₚ [::]
  1183. | permutation_skip x s1 s2: s1 ≡ₚ s2 -> (x :: s1) ≡ₚ (x :: s2)
  1184. | permutation_swap x y s1 s2: s1 ≡ₚ s2 -> [:: x, y & s1] ≡ₚ [:: y, x & s2]
  1185. | permutation_trans t s1 s2: s1 ≡ₚ t -> t ≡ₚ s2 -> s1 ≡ₚ s2
  1186. where "x ≡ₚ y" := (perm x y).
  1187.  
  1188. Section Perm.
  1189. Context {A : Type}.
  1190.  
  1191.  
  1192. Lemma perm_refl (s : seq A) : s ≡ₚ s.
  1193. Proof.
  1194. elim: s=> [| a l IHl].
  1195. by apply: permutation_nil.
  1196. by apply: permutation_skip.
  1197. Qed.
  1198.  
  1199. Lemma perm_nil (s : seq A) : [::] ≡ₚ s <-> s = [::].
  1200. Proof.
  1201. split.
  1202. move E: {1}[::]=>l H.
  1203. move: H {E}(esym E).
  1204. by elim=>//??? _ IH1 _ IH2 /IH1/IH2.
  1205. move=>->.
  1206. by apply: permutation_nil.
  1207. Qed.
  1208.  
  1209. Lemma perm_sym (s1 s2: seq A) : s1 ≡ₚ s2 <-> s2 ≡ₚ s1.
  1210. Proof.
  1211. suff {s1 s2} L : forall s1 s2, s1 ≡ₚ s2 -> s2 ≡ₚ s1.
  1212. split;
  1213. by apply: L.
  1214. move => T s1 s2.
  1215. elim {s1 s2} =>[
  1216. |x s1 s2 HP12 HP32
  1217. |x y s1 s2 HP12 HP21
  1218. |s1 s2 s3 HP21 HP12 HP13 HP31].
  1219. + by apply: permutation_nil.
  1220. + by apply: permutation_skip.
  1221. + by apply: permutation_swap.
  1222. + by apply: permutation_trans HP31 HP12.
  1223. Qed.
  1224.  
  1225. Lemma perm_trans (s2 s1 s3: seq A) : s1 ≡ₚ s2 -> s2 ≡ₚ s3 -> s1 ≡ₚ s3.
  1226. Proof.
  1227. by apply: permutation_trans.
  1228. Qed.
  1229.  
  1230. Lemma perm_in (s1 s2: seq A) x : s1 ≡ₚ s2 -> PIn x s1 -> PIn x s2.
  1231. Proof.
  1232. elim =>
  1233. [|x' s3 s4 Hperm34 Hin34
  1234. |x' y' s3 s4 Hperm34 Hin34
  1235. | s4 s3 s5 Hperm34 Hin34 Hperm45 Hin45];
  1236. rewrite ?PIn_cons_or.
  1237. - by [].
  1238. - move => [<-|Hin3].
  1239. by left.
  1240. right.
  1241. by apply: Hin34.
  1242. - move =>[<-|[<-|Hin3]].
  1243. + right.
  1244. by left.
  1245. + by left.
  1246. + repeat right.
  1247. by apply: Hin34.
  1248. - move => Hin3.
  1249. have Hin4 := Hin34 Hin3.
  1250. by apply: Hin45.
  1251. Qed.
  1252.  
  1253. Lemma perm_catC (s1 s2: seq A) : (s1 ++ s2) ≡ₚ (s2 ++ s1).
  1254. Proof.
  1255. elim: s1 s2=>[|x s1 IH1] s2 /=.
  1256. rewrite cats0.
  1257. by apply: perm_refl.
  1258. apply: (@perm_trans (x::s2++s1)).
  1259. by apply: permutation_skip.
  1260. elim: s2=>[|y s2 IH2] //=.
  1261. by apply: perm_refl.
  1262. apply: (@perm_trans (y::x::s2++s1)).
  1263. apply: permutation_swap.
  1264. by apply: perm_refl.
  1265. by apply: permutation_skip.
  1266. Qed.
  1267.  
  1268. Lemma perm_cat2lL (s s1 s2: seq A) : s1 ≡ₚ s2 -> (s ++ s1) ≡ₚ (s ++ s2).
  1269. Proof.
  1270. elim: s=>[//|e s IH /IH];
  1271. by apply: permutation_skip.
  1272. Qed.
  1273.  
  1274. Lemma perm_cat2rL (s s1 s2: seq A) : s1 ≡ₚ s2 -> (s1 ++ s) ≡ₚ (s2 ++ s).
  1275. Proof.
  1276. move=>?.
  1277. apply: (@perm_trans (s ++ s1)).
  1278. by apply: perm_catC.
  1279. apply: (@perm_trans (s ++ s2)).
  1280. by apply: perm_cat2lL.
  1281. by apply: perm_catC.
  1282. Qed.
  1283.  
  1284. Lemma perm_catL (s1 t1 s2 t2: seq A) :
  1285. s1 ≡ₚ s2 -> t1 ≡ₚ t2 -> (s1 ++ t1) ≡ₚ (s2 ++ t2).
  1286. Proof.
  1287. move/(perm_cat2rL t1)=>H1 /(perm_cat2lL s2).
  1288. by apply: perm_trans.
  1289. Qed.
  1290.  
  1291. Lemma perm_cat_consL (s1 t1 s2 t2: seq A) x :
  1292. s1 ≡ₚ s2 -> t1 ≡ₚ t2 -> (s1 ++ x :: t1) ≡ₚ (s2 ++ x :: t2).
  1293. Proof.
  1294. move=>*.
  1295. apply: perm_catL.
  1296. by [].
  1297. by apply: permutation_skip.
  1298. Qed.
  1299.  
  1300. Lemma perm_cons_catCA (s1 s2: seq A) x : (x :: s1 ++ s2) ≡ₚ (s1 ++ x :: s2).
  1301. Proof.
  1302. rewrite -cat1s -(cat1s _ s2) !catA.
  1303. by apply/perm_cat2rL/perm_catC.
  1304. Qed.
  1305.  
  1306. Lemma perm_cons_catAC (s1 s2: seq A) x : (s1 ++ x :: s2) ≡ₚ (x :: s1 ++ s2).
  1307. Proof.
  1308. by apply/perm_sym/perm_cons_catCA.
  1309. Qed.
  1310.  
  1311. Lemma perm_cons_cat_consL (s1 s2 s: seq A) x :
  1312. s ≡ₚ (s1 ++ s2) -> (x :: s) ≡ₚ (s1 ++ x :: s2).
  1313. Proof.
  1314. move=>?.
  1315. apply: (@perm_trans (x :: (s1 ++ s2))).
  1316. by apply: permutation_skip.
  1317. by apply: perm_cons_catCA.
  1318. Qed.
  1319.  
  1320. Lemma perm_size (l1 l2: seq A): l1 ≡ₚ l2 -> size l1 = size l2.
  1321. Proof.
  1322. by elim=>//=???? =>[|?|]->.
  1323. Qed.
  1324.  
  1325. Lemma perm_cat_consR (s1 s2 t1 t2: seq A) x :
  1326. (s1 ++ x :: t1) ≡ₚ (s2 ++ x :: t2) -> (s1 ++ t1) ≡ₚ (s2 ++ t2).
  1327. Proof.
  1328. move: s1 t1 s2 t2 x.
  1329. suff H:
  1330. forall (r1 r2: seq A), r1 ≡ₚ r2 -> forall x s1 t1 s2 t2,
  1331. r1 = s1 ++ x :: t1 -> r2 = s2 ++ x :: t2 -> (s1 ++ t1) ≡ₚ (s2 ++ t2).
  1332. move=>s1 t1 s2 t2 x /H H'. by apply: H'.
  1333. move => r1 r2.
  1334. elim {r1 r2}=> [];
  1335. last 1 first.
  1336. - move=>s2 s1 s3 H1 IH1 H2 IH2 x r1 t1 r2 t2 E1 E2.
  1337. case: (@PIn_split1 _ x s2).
  1338. - apply: perm_in H1 _.
  1339. rewrite E1 PIn_app.
  1340. right.
  1341. left.
  1342. - move=>s4 [s5] E.
  1343. apply: (@perm_trans (s4++s5)).
  1344. by apply: IH1 E1 E.
  1345. by apply: IH2 E E2.
  1346. - by move=>x [].
  1347. - move=>x t1 t2 H IH y [|b s1] s2 [|c p1] p2 /= [E1 E2] [E3 E4];
  1348. subst x;
  1349. move: H;
  1350. rewrite ?E1 ?E2 ?E3 ?E4 =>// H.
  1351. - subst y.
  1352. apply: perm_trans H _.
  1353. rewrite perm_sym.
  1354. apply: perm_cons_cat_consL.
  1355. by apply: perm_refl.
  1356. - apply: perm_trans H.
  1357. apply: perm_cons_cat_consL.
  1358. by apply: perm_refl.
  1359. - apply: permutation_skip.
  1360. by apply: IH E2 E4.
  1361. move=>x y p1 p2 H IH z [|b s1] t1 [|c s2] t2 /= [E1 E2] [E3 E4];
  1362. subst x y;
  1363. move : H IH;
  1364. rewrite -?E2 -?E4 => H IH.
  1365. - by apply: permutation_skip.
  1366. - case: s2 E4=>/=[|a s2][<-]=>[|E4];
  1367. apply: permutation_skip.
  1368. by [].
  1369. subst p2.
  1370. apply: perm_trans H _.
  1371. by apply: perm_cons_catAC.
  1372. - case: s1 E2=>/=[|a s1][<-]=>[|E2];
  1373. apply: permutation_skip.
  1374. by [].
  1375. subst p1.
  1376. apply: perm_trans H.
  1377. by apply: perm_cons_catCA.
  1378. case: s1 E2=>/=[|a s1][->]=>E2;
  1379. case: s2 E4=>/=[|d s2][->]=>E4;
  1380. move : H IH;
  1381. rewrite ?E2 ?E4 => H IH.
  1382. - by apply: permutation_skip.
  1383. - apply: (@perm_trans [:: d, z & s2 ++ t2]);
  1384. last first.
  1385. apply: permutation_swap.
  1386. by apply: perm_refl.
  1387. apply: permutation_skip.
  1388. apply: perm_trans H _.
  1389. by apply/perm_cons_catAC.
  1390. - apply: (@perm_trans [:: a, z & s1 ++ t1]).
  1391. apply: permutation_swap.
  1392. by apply: perm_refl.
  1393. apply: permutation_skip.
  1394. by apply/perm_trans/H/perm_cons_catCA.
  1395. - apply: permutation_swap.
  1396. by apply: IH.
  1397. Qed.
  1398.  
  1399. Lemma perm_cons x (s1 s2: seq A): (x :: s1) ≡ₚ (x :: s2) <-> s1 ≡ₚ s2.
  1400. Proof.
  1401. split.
  1402. by apply/(@perm_cat_consR [::] [::]).
  1403. by apply: permutation_skip.
  1404. Qed.
  1405.  
  1406. Lemma perm_cat2l (s s1 s2: seq A): (s ++ s1) ≡ₚ (s ++ s2) <-> s1 ≡ₚ s2.
  1407. Proof.
  1408. split.
  1409. by elim: s=>// ??? /perm_cons.
  1410. by apply: perm_cat2lL.
  1411. Qed.
  1412.  
  1413. Lemma perm_cat2r (s s1 s2: seq A) : (s1 ++ s) ≡ₚ (s2 ++ s) <-> s1 ≡ₚ s2.
  1414. Proof.
  1415. split;
  1416. last by apply: perm_cat2rL.
  1417. elim: s=>[|??? /perm_cat_consR].
  1418. by rewrite !cats0.
  1419. by [].
  1420. Qed.
  1421.  
  1422. Lemma perm_catAC (s1 s2 s3: seq A) : ((s1 ++ s2) ++ s3) ≡ₚ ((s1 ++ s3) ++ s2).
  1423. Proof.
  1424. rewrite -!catA perm_cat2l.
  1425. by apply: perm_catC.
  1426. Qed.
  1427.  
  1428. Lemma perm_catCA (s1 s2 s3: seq A) : (s1 ++ s2 ++ s3) ≡ₚ (s2 ++ s1 ++ s3).
  1429. Proof.
  1430. rewrite !catA perm_cat2r.
  1431. by apply: perm_catC.
  1432. Qed.
  1433.  
  1434. Lemma perm_cons_cat_cons x (s1 s2 s: seq A) :
  1435. (x :: s) ≡ₚ (s1 ++ x :: s2) <-> s ≡ₚ (s1 ++ s2).
  1436. Proof.
  1437. split.
  1438. by apply: (@perm_cat_consR [::]).
  1439. by apply: perm_cons_cat_consL.
  1440. Qed.
  1441.  
  1442. Lemma perm_cat_cons x (s1 s2 t1 t2: seq A) :
  1443. (s1 ++ x :: t1) ≡ₚ (s2 ++ x :: t2) <-> (s1 ++ t1) ≡ₚ (s2 ++ t2).
  1444. Proof.
  1445. split=>[|H].
  1446. by apply: perm_cat_consR.
  1447. apply: (@perm_trans (x::s1++t1)).
  1448. by apply: perm_cons_catAC.
  1449. apply: (@perm_trans (x::s2++t2)).
  1450. by apply: permutation_skip.
  1451. rewrite perm_sym.
  1452. apply: perm_cons_catAC.
  1453. Qed.
  1454.  
  1455. Lemma perm_empty_r (s: seq A) : s = [::] <-> s ≡ₚ [::].
  1456. Proof.
  1457. split.
  1458. move ->.
  1459. apply: perm_refl.
  1460. move Heqs' : [::] => s' HP.
  1461. rewrite -Heqs'.
  1462. elim : HP Heqs' => {s s'} [
  1463. |x' s1 s2 HP12 IH
  1464. |x' y s1 s2 HP12 Heq
  1465. |s2 s1 s3 HP12 Heq12 HP23 Heq23] H //.
  1466. apply: Heq12.
  1467. symmetry.
  1468. by apply: Heq23.
  1469. Qed.
  1470.  
  1471. Lemma perm_empty_l (s: seq A) : [::] = s <-> [::] ≡ₚ s.
  1472. Proof.
  1473. rewrite perm_sym -perm_empty_r.
  1474. split;
  1475. by move ->.
  1476. Qed.
  1477.  
  1478. Lemma perm_singleton_r x (s: seq A): s = [::x] <-> s ≡ₚ [::x].
  1479. Proof.
  1480. split.
  1481. move ->.
  1482. apply: perm_refl.
  1483. move Heqs' : [::x] => s' HP.
  1484. rewrite -Heqs'.
  1485. elim : HP Heqs' => {s s'} [
  1486. |x' s1 s2 HP12 IH
  1487. |x' y s1 s2 HP12 Heq
  1488. |s2 s1 s3 HP12 Heq12 HP23 Heq23] //=.
  1489. - move => [<-] Hnil.
  1490. move: HP12.
  1491. rewrite -Hnil -perm_empty_r.
  1492. by move ->.
  1493. - move => Heq3.
  1494. apply: Heq12.
  1495. symmetry.
  1496. by apply: Heq23.
  1497. Qed.
  1498.  
  1499. Lemma perm_singleton_l x (s: seq A): [::x] = s <-> [::x] ≡ₚ s.
  1500. Proof.
  1501. rewrite perm_sym -perm_singleton_r.
  1502. split;
  1503. by move ->.
  1504. Qed.
  1505.  
  1506. Lemma foldr_perm (f: A -> A -> A) b (s1 s2: seq A):
  1507. associative f ->
  1508. commutative f ->
  1509. s1 ≡ₚ s2 -> foldr f b s1 = foldr f b s2.
  1510. Proof.
  1511. move => Hassoc Hcomm.
  1512. elim => {s1 s2} [
  1513. |x' s1 s2 HP12 IH
  1514. |x' y s1 s2 HP12 Heq
  1515. |s2 s1 s3 HP12 Heq12 HP23 Heq23] /=.
  1516. - by [].
  1517. - by rewrite IH.
  1518. - by rewrite Hassoc (@Hcomm x') -Hassoc Heq.
  1519. - by rewrite Heq12 Heq23.
  1520. Qed.
  1521.  
  1522. End Perm.
  1523.  
  1524. (* perm and map *)
  1525. Lemma pperm_map A B (f : A -> B) (s1 s2 : seq A) :
  1526. s1 ≡ₚ s2 -> (map f s1) ≡ₚ (map f s2).
  1527. Proof.
  1528. elim => [
  1529. |x s3 s4 HP34 HPmap34
  1530. |x y s3 s4 HP34 HPmap34
  1531. |s3 s4 s5 HP34 HPmap34 Hp34 HPmap45] /=.
  1532. - apply: perm_refl.
  1533. - by rewrite perm_cons.
  1534. - by apply: permutation_swap.
  1535. - apply: perm_trans.
  1536. apply: HPmap34.
  1537. apply: HPmap45.
  1538. Qed.
  1539.  
  1540. (* mapping to ssreflect decidable perm *)
  1541. Lemma perm_eq_perm (A : eqType) (s1 s2 : seq A) :
  1542. reflect (s1 ≡ₚ s2) (perm_eq s1 s2).
  1543. Proof.
  1544. apply: (iffP idP).
  1545. elim: s2 s1 =>[s1 /ssreflect.seq.perm_size/size0nil->// | x s2 IH s1 H].
  1546. - apply: perm_refl.
  1547. - move: (seq.perm_mem H x).
  1548. rewrite mem_head=>H'.
  1549. move: H' H.
  1550. move/splitPr=>[p1 p2].
  1551. rewrite -cat1s ssreflect.seq.perm_catCA.
  1552. rewrite ssreflect.seq.perm_cons=>/IH.
  1553. by rewrite -[_::s2]cat0s perm_cat_cons.
  1554. elim=>[|||??? _ H1 _ H2] /=.
  1555. - by [].
  1556. - move => x s3 s4.
  1557. by rewrite ssreflect.seq.perm_cons.
  1558. - move => x y s3 s4.
  1559. rewrite -![[:: _, _ & _]]/([::_] ++ [::_] ++ _) ssreflect.seq.perm_catCA.
  1560. by rewrite !ssreflect.seq.perm_cat2l.
  1561. - by apply: ssreflect.seq.perm_trans H1 H2.
  1562. Qed.
  1563.  
  1564.  
  1565. (* The definition and lemmas for submseteq are taken straight from stdpp. I *)
  1566. (* guess I am too dump to come up with that myself :\ *)
  1567.  
  1568. (* A seq [l2] submseteq a seq [l1] if [l2] is obtained by removing elements *)
  1569. (* from [l1] while possiblity changing the order. *)
  1570. Inductive submseteq {A} : seq A -> seq A -> Prop :=
  1571. | submseteq_nil : submseteq [::] [::]
  1572. | submseteq_skip x l1 l2 : submseteq l1 l2 -> submseteq (x :: l1) (x :: l2)
  1573. | submseteq_swap x y l : submseteq (y :: x :: l) (x :: y :: l)
  1574. | submseteq_cons x l1 l2 : submseteq l1 l2 -> submseteq l1 (x :: l2)
  1575. | submseteq_trans l1 l2 l3 : submseteq l1 l2 -> submseteq l2 l3 -> submseteq l1 l3.
  1576. Infix "⊆+" := submseteq (at level 70).
  1577.  
  1578. Lemma submseteq_size A (l1 l2: seq A) : l1 ⊆+ l2 -> size l1 <= size l2.
  1579. Proof.
  1580. elim => /=;
  1581. by lia.
  1582. Qed.
  1583.  
  1584. Lemma submseteq_nil_l A (l: seq A) : [::] ⊆+ l.
  1585. Proof.
  1586. elim : l => [|a l IHl].
  1587. by constructor.
  1588. by constructor.
  1589. Qed.
  1590.  
  1591. Lemma submseteq_nil_r A (l: seq A) : l ⊆+ [::] <-> l = [::].
  1592. Proof.
  1593. split;
  1594. last first.
  1595. move ->.
  1596. by constructor.
  1597. move /submseteq_size.
  1598. case : l => [|a l] /=.
  1599. by [].
  1600. by lia.
  1601. Qed.
  1602.  
  1603. Lemma Permutation_submseteq A (l1 l2: seq A) : l1 ≡ₚ l2 -> l1 ⊆+ l2.
  1604. Proof.
  1605. elim => {l1 l2} => [
  1606. |x s1 s2 HP12 HS12
  1607. |x y s1 s2 HP12 HS12
  1608. |s2 s1 s3 HP12 HS12 HP23 HS23].
  1609. - by constructor.
  1610. - by constructor.
  1611. - apply: submseteq_trans.
  1612. apply: submseteq_swap.
  1613. by repeat apply: submseteq_skip.
  1614. - apply: submseteq_trans.
  1615. by apply: HS12.
  1616. by apply: HS23.
  1617. Qed.
  1618.  
  1619. Lemma submseteq_Permutation A (l1 l2: seq A) : l1 ⊆+ l2 -> exists k, l2 ≡ₚ l1 ++ k.
  1620. Proof.
  1621. elim => {l1 l2} [
  1622. |a l1 l2 HS12 [k HP12k]
  1623. |a b l1
  1624. |a l1 l2 HP12 [k HP12k]
  1625. |l1 l2 l3 HP12 [k HP21k] HP23 [k' HP32k']].
  1626. - exists [::] => /=.
  1627. apply: perm_refl.
  1628. - exists k.
  1629. rewrite cat_cons.
  1630. by apply: permutation_skip.
  1631. - exists [::].
  1632. rewrite cats0.
  1633. apply: permutation_swap.
  1634. apply: perm_refl.
  1635. - exists (a :: k).
  1636. by rewrite perm_cons_cat_cons.
  1637. - exists (k ++ k').
  1638. apply: permutation_trans.
  1639. apply: HP32k'.
  1640. by rewrite catA perm_cat2r.
  1641. Qed.
  1642. Lemma seq_app_size A (l1 l2: seq A):
  1643. size (l1 ++ l2) = size l1 + size l2.
  1644. Proof.
  1645. elim : l1 l2 => [|a l IHl] l2 /=.
  1646. by lia.
  1647. rewrite IHl.
  1648. by lia.
  1649. Qed.
  1650.  
  1651. Lemma submseteq_Permutation_size_le A (l1 l2: seq A) :
  1652. size l2 <= size l1 -> l1 ⊆+ l2 -> l1 ≡ₚ l2.
  1653. Proof.
  1654. move => Hl12 HS12.
  1655. move : (submseteq_Permutation HS12) =>[[|a s3]].
  1656. by rewrite cats0 perm_sym.
  1657. rewrite perm_sym.
  1658. move => /Permutation_submseteq/submseteq_size.
  1659. rewrite seq_app_size /=.
  1660. by lia.
  1661. Qed.
  1662.  
  1663. Lemma submseteq_Permutation_size_eq A (l1 l2: seq A) :
  1664. size l2 = size l1 -> l1 ⊆+ l2 -> l1 ≡ₚ l2.
  1665. Proof.
  1666. move => Hl12.
  1667. apply submseteq_Permutation_size_le.
  1668. by lia.
  1669. Qed.
  1670.  
  1671. Lemma submseteq_Permutation_alt A (l1 l2: seq A):
  1672. l1 ⊆+ l2 -> l2 ⊆+ l1 -> l1 ≡ₚ l2.
  1673. move => HS12 HS21.
  1674. apply: submseteq_Permutation_size_eq;
  1675. last by [].
  1676. move: HS12 HS21.
  1677. move /submseteq_size => Hl12 /submseteq_size => Hl21.
  1678. by lia.
  1679. Qed.
  1680.  
  1681. Lemma submseteq_inserts_l A (l1 l2 l3: seq A):
  1682. l1 ⊆+ l2 -> l1 ⊆+ l3 ++ l2.
  1683. Proof.
  1684. elim : l3 l1 l2 => [|a l3 IHl] l1 l2 HS12 /=.
  1685. by [].
  1686. constructor.
  1687. by apply: IHl.
  1688. Qed.
  1689.  
  1690. Lemma Puniq_submseteq A (l k: seq A) :
  1691. PUniq l -> (forall x, PIn x l -> PIn x k) -> l ⊆+ k.
  1692. Proof.
  1693. move => Huniq.
  1694. elim : Huniq k => {l} [| a l Hnotinl Huniql IHl] k Hinin.
  1695. by apply: submseteq_nil_l.
  1696. have Hinak: PIn a k.
  1697. apply: Hinin.
  1698. by apply: pin_here.
  1699. move :(@PIn_split1 _ a k Hinak) => [s1 [s2 Hk]].
  1700. subst.
  1701. apply: (@submseteq_trans _ _ (a:: s1 ++ s2));
  1702. last first.
  1703. apply: Permutation_submseteq.
  1704. apply: perm_cons_catCA.
  1705. constructor.
  1706. apply: IHl => x Hin.
  1707. have Hororor: PIn x s1 \/ x = a \/ PIn x s2.
  1708. rewrite -PIn_cons_or -PIn_app.
  1709. apply: Hinin.
  1710. by right.
  1711. rewrite PIn_app.
  1712. move : Hororor Hin.
  1713. move => [Hin1|[->|Hin2]] Hinl.
  1714. - by left.
  1715. - by [].
  1716. - by right.
  1717. Qed.
  1718.  
  1719. Lemma Puniq_Permutation A (l1 l2: seq A) :
  1720. PUniq l1 -> PUniq l2 -> (forall x, PIn x l1 <-> PIn x l2) -> l1 ≡ₚ l2.
  1721. Proof.
  1722. move => Huniq1 Huniq2 Hinin.
  1723. apply: submseteq_Permutation_alt;
  1724. apply: Puniq_submseteq => //;
  1725. move => x;
  1726. by rewrite Hinin.
  1727. Qed.
  1728.  
  1729.  
  1730. (*nth element with none *)
  1731. Fixpoint nth_error A (l:list A) (n:nat) : option A :=
  1732. match n, l with
  1733. | O, a :: _ => Some a
  1734. | S n', _ :: l => nth_error l n'
  1735. | _, _ => None
  1736. end.
  1737.  
  1738. Lemma nth_error_map_some A B (s: seq A) a i (f: A-> B):
  1739. nth_error s i = Some a ->
  1740. nth_error (map f s) i = Some (f a).
  1741. Proof.
  1742. elim: s i => [|a' s IHs] [|i]//=.
  1743. by move => [->].
  1744. by apply: IHs.
  1745. Qed.
  1746.  
  1747. Lemma nth_error_map_none A B (s: seq A) i (f: A-> B):
  1748. nth_error s i = None ->
  1749. nth_error (map f s) i = None.
  1750. Proof.
  1751. elim: s i => [|a' s IHs] [|i]//=.
  1752. by apply: IHs.
  1753. Qed.
  1754.  
  1755. Lemma nth_error_map_some_ex A B (s: seq A) a i (f: A-> B):
  1756. nth_error (map f s) i = Some a ->
  1757. exists b,
  1758. nth_error s i = Some b /\ a = f b.
  1759. Proof.
  1760. elim: s i=> [|e s IHs] [|i] //=.
  1761. move => [?].
  1762. by exists e.
  1763. by apply: IHs.
  1764. Qed.
  1765.  
  1766.  
  1767. Lemma nth_error_size_some {A B} (a: A) la (lb: seq B) idx:
  1768. size la = size lb ->
  1769. nth_error la idx = Some a ->
  1770. exists b, nth_error lb idx = Some b.
  1771. Proof.
  1772. elim: la lb idx => [|a' la IHla] [|b' lb] [|idx] //= [Hsize].
  1773. move => _.
  1774. by exists b'.
  1775. by apply: IHla.
  1776. Qed.
  1777.  
  1778. Lemma nth_error_size_none {A B} (la: seq A) (lb: seq B) idx:
  1779. size la = size lb ->
  1780. nth_error la idx = None ->
  1781. nth_error lb idx = None.
  1782. Proof.
  1783. elim: la lb idx => [|a' la IHla] /= [|b' lb] [|idx] //= [Hsize].
  1784. by apply: IHla.
  1785. Qed.
  1786.  
  1787. Lemma nth_error_app1 A (l l': seq A) n : n < size l ->
  1788. nth_error (l++l') n = nth_error l n.
  1789. Proof.
  1790. elim: l l' n => [|a l IHl] l' [|n]//= Hlt.
  1791. by apply: IHl.
  1792. Qed.
  1793.  
  1794. Lemma nth_error_app2 A (l l': seq A) n : n >= size l ->
  1795. nth_error (l++l') n = nth_error l' (n - size l).
  1796. Proof.
  1797. elim: l l' n => [|a l IHl] l' [|n] //= Hsize.
  1798. replace (n.+1 - (size l).+1) with (n - (size l)) by lia.
  1799. by apply: IHl.
  1800. Qed.
  1801.  
  1802. Lemma pin_nth_error_some1 A (a: A) s:
  1803. PIn a s -> exists idx, nth_error s idx = Some a.
  1804. Proof.
  1805. elim => {a s}[a s|a b s Hin].
  1806. by exists 0.
  1807. move => [idx Hnth_error].
  1808. by exists idx.+1.
  1809. Qed.
  1810.  
  1811. Lemma pin_nth_error_some2 A (a: A) s idx:
  1812. nth_error s idx = Some a -> PIn a s.
  1813. Proof.
  1814. elim: s a idx => [|a' s IHs] a [|idx] //=.
  1815. move => [->].
  1816. by apply: pin_here.
  1817. move => Hnth_error.
  1818. apply: pin_future.
  1819. apply: IHs.
  1820. by apply: Hnth_error.
  1821. Qed.
  1822.  
  1823. Lemma pin_nth_error_some A (a: A) s:
  1824. PIn a s <-> exists idx, nth_error s idx = Some a.
  1825. Proof.
  1826. split.
  1827. by apply: pin_nth_error_some1.
  1828. move => [].
  1829. by apply: pin_nth_error_some2.
  1830. Qed.
  1831.  
  1832. Lemma zip_nth_error_some1 {A B} (la: seq A) (lb: seq B) idx a b:
  1833. (nth_error la idx = Some a /\ nth_error lb idx = Some b) ->
  1834. nth_error (zip la lb) idx = Some (a, b).
  1835. Proof.
  1836. move => [].
  1837. elim: la lb idx => [|a' la IHla] [|b' lb] [|idx] //=.
  1838. by move => [->] [->].
  1839. by apply: IHla.
  1840. Qed.
  1841.  
  1842. Lemma zip_nth_error_some2 {A B} (la: seq A) (lb: seq B) idx a b:
  1843. nth_error (zip la lb) idx = Some (a, b) ->
  1844. (nth_error la idx = Some a /\ nth_error lb idx = Some b).
  1845. Proof.
  1846. elim: la lb idx => [|a' la IHla] [|b' lb] [|idx] //=.
  1847. by move => [-> ->].
  1848. by move /IHla.
  1849. Qed.
  1850.  
  1851. Lemma zip_nth_error_some {A B} (la: seq A) (lb: seq B) idx a b:
  1852. (nth_error la idx = Some a /\ nth_error lb idx = Some b) <->
  1853. nth_error (zip la lb) idx = Some (a, b).
  1854. Proof.
  1855. split.
  1856. by apply: zip_nth_error_some1.
  1857. by apply: zip_nth_error_some2.
  1858. Qed.
  1859.  
  1860. (* l and l' are identical except for one element that satisfies R *)
  1861. Definition on_one A (R: A -> A -> Prop) l l' :=
  1862. exists l0 l1 x y, l = l0 ++ x :: l1 /\ l' = l0 ++ y :: l1 /\ R x y.
  1863.  
  1864. Lemma on_one_cons A R l l' (a b: A) :
  1865. on_one R (a::l) (b::l') <->
  1866. (R a b /\ l = l') \/ (a = b /\ on_one R l l').
  1867. Proof.
  1868. split.
  1869. move => [[|c l1]] [l2] [x] [y] /= [[-> ->]] [[-> ->]].
  1870. by left.
  1871. right.
  1872. split => //.
  1873. by exists l1, l2, x ,y.
  1874. move => [[HR ->]|[-> ]].
  1875. by exists [::], l', a, b.
  1876. move => [l1] [l2] [x] [y] [->] [->] HR.
  1877. by exists (b::l1), l2, x, y.
  1878. Qed.
  1879.  
  1880. Lemma on_one_singleton A (R: A -> A -> Prop) x y : R x y -> @on_one A R [:: x] [:: y].
  1881. Proof.
  1882. move => HR.
  1883. by exists [::], [::], x ,y.
  1884. Qed.
  1885.  
  1886.  
  1887. Lemma on_one_app A (R : A -> A-> Prop) l l' l1 l2:
  1888. on_one R l l' -> on_one R (l1 ++ l ++ l2) (l1 ++ l' ++ l2).
  1889. move => [l3] [l4] [x] [y] [->] [->] HR /=.
  1890. exists (l1 ++ l3), (l4 ++ l2), x, y.
  1891. by rewrite -!catA.
  1892. Qed.
  1893.  
  1894. Definition seq_forall_pair A B (R: A -> B -> Prop) s1 s2 :=
  1895. size s1 = size s2 /\ forall ts, PIn ts (zip s1 s2) -> R (ts.1) (ts.2).
  1896.  
  1897.  
  1898. Lemma seq_forall_pair_cons A1 A2 (a1: A1) (a2: A2) s1 s2 (R: A1 -> A2 -> Prop):
  1899. seq_forall_pair R (a1::s1) (a2::s2) <->
  1900. R a1 a2 /\ seq_forall_pair R s1 s2.
  1901. Proof.
  1902. split => /=.
  1903. move => [[Hsize]] Hforall.
  1904. repeat split => //.
  1905. have := Hforall (a1, a2) => /= HRa12.
  1906. apply: HRa12.
  1907. by apply: pin_here.
  1908. move => ts Hin.
  1909. apply: Hforall => /=.
  1910. by apply: pin_future.
  1911. rewrite /seq_forall_pair /=.
  1912. move => [HR [-> Hforall]].
  1913. split => //.
  1914. move => [a1' a2'] /=.
  1915. rewrite PIn_cons_or => [[[-> ->]|]] // Hin.
  1916. by have := Hforall _ Hin => /=.
  1917. Qed.
  1918.  
  1919. Lemma seq_forall_pair_empty
  1920. A B (R: A -> B -> Prop):
  1921. seq_forall_pair R [::] [::].
  1922. Proof.
  1923. split => // ts.
  1924. by rewrite PIn_empty_false_iff.
  1925. Qed.
  1926.  
  1927. Lemma seq_forall_pair_refl
  1928. A1 s (R: A1 -> A1 -> Prop):
  1929. (forall a, R a a) ->
  1930. seq_forall_pair R s s.
  1931. Proof.
  1932. move => Hrefl.
  1933. elim: s=> [|a s IHs];
  1934. last by rewrite seq_forall_pair_cons.
  1935. split => //.
  1936. move => /= ts.
  1937. by rewrite PIn_empty_false_iff.
  1938. Qed.
  1939.  
  1940. Lemma seq_pair_forall_empty_consr A B (R : A -> B -> Prop ) a s:
  1941. seq_forall_pair R [::] (a::s) <-> False.
  1942. Proof.
  1943. split => //.
  1944. by move => [].
  1945. Qed.
  1946.  
  1947. Lemma seq_pair_forall_empty_consl A B (R : A -> B -> Prop ) a s:
  1948. seq_forall_pair R (a::s) [::] <-> False.
  1949. Proof.
  1950. split => //.
  1951. by move => [].
  1952. Qed.
  1953.  
  1954. Lemma seq_pair_forall_emptyl A B (R : A -> B -> Prop ) s:
  1955. seq_forall_pair R [::] s <-> s = [::].
  1956. Proof.
  1957. elim: s => [|a s IH].
  1958. split => // _.
  1959. by apply: seq_forall_pair_empty.
  1960. split => //.
  1961. by rewrite seq_pair_forall_empty_consr.
  1962. Qed.
  1963.  
  1964. Lemma seq_pair_forall_emptyr A B (R : A -> B -> Prop ) s:
  1965. seq_forall_pair R s [::] <-> s = [::].
  1966. Proof.
  1967. elim: s => [|a s IH].
  1968. split => // _.
  1969. by apply: seq_forall_pair_empty.
  1970. split => //.
  1971. by rewrite seq_pair_forall_empty_consl.
  1972. Qed.
  1973.  
  1974. Lemma seq_pair_forall_pair_singleton A B a1 a2 (R : A -> B -> Prop):
  1975. seq_forall_pair R [:: a1] [:: a2] <->
  1976. R a1 a2.
  1977. Proof.
  1978. rewrite /seq_forall_pair /=.
  1979. split.
  1980. move => [_ HR].
  1981. have := (HR (a1, a2)) => /= HR'.
  1982. apply: HR'.
  1983. by rewrite -PIn_singlton.
  1984. move => HR.
  1985. split => //.
  1986. move => [??].
  1987. by rewrite -PIn_singlton => [[-> ->]].
  1988. Qed.
  1989.  
  1990. Lemma seq_forall_pair_app A B s1 s2 s3 s4 (R : A -> B -> Prop ):
  1991. seq_forall_pair R s1 s3 ->
  1992. seq_forall_pair R s2 s4 ->
  1993. seq_forall_pair R (s1++s2) (s3++s4).
  1994. Proof.
  1995. elim: s1 s3 s2 s4 => [|a1 s1 IHs1] [|a3 s3] s2 s4 //;
  1996. rewrite ?seq_pair_forall_emptyl ?seq_pair_forall_emptyr //=.
  1997. rewrite !seq_forall_pair_cons.
  1998. move => [HR13] Hforall13 Hforall24.
  1999. split => //.
  2000. by apply: IHs1.
  2001. Qed.
  2002.  
  2003. Lemma seq_forall_pair_rcons1 A1 A2 (a1: A1) (a2: A2) s1 s2 (R: A1 -> A2 -> Prop):
  2004. seq_forall_pair R (rcons s1 a1) (rcons s2 a2) ->
  2005. R a1 a2 /\ seq_forall_pair R s1 s2.
  2006. Proof.
  2007. rewrite /seq_forall_pair !size_rcons => [[[Hsize]]].
  2008. move => Hforall.
  2009. repeat split => //.
  2010. have := Hforall (a1, a2) => /= Hforall12.
  2011. apply: Hforall12.
  2012. rewrite zip_rcons // PIn_rcons_or.
  2013. by left.
  2014. move => ts Hin.
  2015. apply: Hforall.
  2016. rewrite zip_rcons // PIn_rcons_or.
  2017. by right.
  2018. Qed.
  2019.  
  2020. Lemma seq_forall_pair_rcons2 A1 A2 (a1: A1) (a2: A2) s1 s2 (R: A1 -> A2 -> Prop):
  2021. R a1 a2 -> seq_forall_pair R s1 s2 ->
  2022. seq_forall_pair R (rcons s1 a1) (rcons s2 a2).
  2023. Proof.
  2024. move => HR [Hsize Hforall].
  2025. split.
  2026. by rewrite !size_rcons Hsize.
  2027. move => ts.
  2028. rewrite zip_rcons // PIn_rcons_or => [[->|Hin]] //.
  2029. by apply: Hforall.
  2030. Qed.
  2031.  
  2032. Lemma seq_forall_pair_rcons A1 A2 (a1: A1) (a2: A2) s1 s2 (R: A1 -> A2 -> Prop):
  2033. seq_forall_pair R (rcons s1 a1) (rcons s2 a2) <->
  2034. R a1 a2 /\ seq_forall_pair R s1 s2.
  2035. Proof.
  2036. split.
  2037. by apply: seq_forall_pair_rcons1.
  2038. move => [??].
  2039. by apply: seq_forall_pair_rcons2.
  2040. Qed.
  2041.  
  2042. Lemma seq_forall_pair_rconsl_ex A1 A2 (a1: A1) s1 s2 (R: A1 -> A2 -> Prop):
  2043. seq_forall_pair R (rcons s1 a1) s2 ->
  2044. exists a2 s3,
  2045. s2 = rcons s3 a2 /\
  2046. R a1 a2 /\ seq_forall_pair R s1 s3.
  2047. Proof.
  2048. elim/last_ind: s2 s1 a1 => [|s2 a2 IH] s1 a1.
  2049. rewrite seq_pair_forall_emptyr rcons_to_cat.
  2050. by elim: s1.
  2051. rewrite seq_forall_pair_rcons => [[HR Hforall]].
  2052. by exists a2, s2.
  2053. Qed.
  2054.  
  2055. Lemma seq_forall_pair_rconsr_ex A1 A2 (a2: A2) s1 s2 (R: A1 -> A2 -> Prop):
  2056. seq_forall_pair R s1 (rcons s2 a2) ->
  2057. exists a1 s3,
  2058. s1 = rcons s3 a1 /\
  2059. R a1 a2 /\ seq_forall_pair R s3 s2.
  2060. Proof.
  2061. elim/last_ind: s1 s2 a2 => [|s1 a1 IH] s2 a2.
  2062. rewrite seq_pair_forall_emptyl rcons_to_cat.
  2063. by elim: s2.
  2064. rewrite seq_forall_pair_rcons => [[HR Hforall]].
  2065. by exists a1, s1.
  2066. Qed.
  2067.  
  2068.  
  2069. Lemma seq_forall_pair_in A1 A2 (a1: A1) (a2: A2) s1 s2 idx (R: A1 -> A2 -> Prop):
  2070. seq_forall_pair R s1 s2 ->
  2071. nth_error s1 idx = Some a1 ->
  2072. nth_error s2 idx = Some a2 ->
  2073. R a1 a2.
  2074. Proof.
  2075. move => [Hsize] Hforall Hin1 Hin2.
  2076. have := Hforall (a1, a2) => /= Hforall'.
  2077. apply: Hforall'.
  2078. rewrite pin_nth_error_some.
  2079. exists idx.
  2080. by rewrite -zip_nth_error_some.
  2081. Qed.
  2082.  
  2083. Lemma seq_forall_pair_map A B C D (s1 :seq C) (s2 :seq D) f g (R : A -> B -> Prop):
  2084. seq_forall_pair R (map f s1) (map g s2) <->
  2085. seq_forall_pair (fun a b => R (f a) (g b)) s1 s2.
  2086. Proof.
  2087. split.
  2088. move => [].
  2089. rewrite !size_map => Hsize Hforall.
  2090. split => //.
  2091. move => [t1 t2] Hin/=.
  2092. have := Hforall (f t1, g t2) => /= Hforall'.
  2093. apply: Hforall'.
  2094. rewrite map_zip2 pin_map.
  2095. by exists (t1, t2).
  2096. move => [Hsize] Hforall.
  2097. split.
  2098. by rewrite !size_map.
  2099. move => [a b].
  2100. rewrite map_zip2 pin_map.
  2101. move => [ts] [[-> ->]].
  2102. by apply: Hforall.
  2103. Qed.
  2104.  
  2105. Lemma seq_pair_forall_left_map A B C (s1 :seq C) s2 f (R : A -> B -> Prop):
  2106. seq_forall_pair R (map f s1) s2 <->
  2107. seq_forall_pair (fun a b => R (f a) b) s1 s2.
  2108. Proof.
  2109. rewrite -(map_id s2).
  2110. by rewrite seq_forall_pair_map map_id.
  2111. Qed.
  2112.  
  2113. Lemma seq_pair_forall_right_map A B D s1 (s2 :seq D) g (R : A -> B -> Prop):
  2114. seq_forall_pair R s1 (map g s2) <->
  2115. seq_forall_pair (fun a b => R a (g b)) s1 s2.
  2116. Proof.
  2117. rewrite -(map_id s1).
  2118. by rewrite seq_forall_pair_map map_id.
  2119. Qed.
  2120.  
  2121. Lemma seq_pair_forall_flip A B s1 s2 (R : A -> B -> Prop):
  2122. seq_forall_pair R s1 s2 <->
  2123. seq_forall_pair (fun x y => R y x) s2 s1.
  2124. Proof.
  2125. split;
  2126. move => [Hsize] Hforall;
  2127. split => //;
  2128. move => [b a];
  2129. rewrite Pin_zip_flip_iff;
  2130. by move /Hforall.
  2131. Qed.
  2132.  
  2133. Lemma seq_forall_pair_app_existsr A B (R : A -> B -> Prop) s1 s2 s3:
  2134. seq_forall_pair R (s1++s2) s3 ->
  2135. exists s4 s5,
  2136. s3 = s4 ++ s5 /\
  2137. seq_forall_pair R s1 s4 /\
  2138. seq_forall_pair R s2 s5.
  2139. Proof.
  2140. elim: s1 s2 s3 => [|a1 s1 IH] /=.
  2141. move => s2 s3 Hforll25.
  2142. exists [::], s3 => /=.
  2143. split => //.
  2144. split=> //.
  2145. by apply: seq_forall_pair_empty.
  2146. move => s2 [|a3 s3].
  2147. by rewrite seq_pair_forall_emptyr.
  2148. rewrite seq_forall_pair_cons => [[HR13 Hforall3]].
  2149. have := IH _ _ Hforall3.
  2150. move => [s4] [s5] [Heq] [Hforall14] Hforall25.
  2151. exists (a3::s4), s5.
  2152. by rewrite Heq seq_forall_pair_cons.
  2153. Qed.
  2154.  
  2155.  
  2156. Inductive SeqForallPair {A B} (R: A -> B -> Prop) : seq A -> seq B -> Prop :=
  2157. | SeqForallPair_empty: SeqForallPair R [::] [::]
  2158. | SeqForallPair_cons a b sa sb: R a b -> SeqForallPair R sa sb -> SeqForallPair R (a::sa) (b::sb).
  2159.  
  2160.  
  2161. Lemma SeqForallPair_in_forall1 A B (R: A -> B-> Prop) sa sb:
  2162. SeqForallPair R sa sb -> seq_forall_pair R sa sb.
  2163. Proof.
  2164. elim => {sa sb} [| a b sa sb HR Hforall IH].
  2165. by apply seq_forall_pair_empty.
  2166. by rewrite seq_forall_pair_cons.
  2167. Qed.
  2168.  
  2169. Lemma SeqForallPair_in_forall2 A B (R: A -> B-> Prop) sa sb:
  2170. seq_forall_pair R sa sb -> SeqForallPair R sa sb.
  2171. Proof.
  2172. elim: sa sb => [|a sa IH] [|b sb] //;
  2173. rewrite ?seq_pair_forall_emptyl ?seq_pair_forall_emptyr //.
  2174. move => ?.
  2175. by apply: SeqForallPair_empty.
  2176. rewrite seq_forall_pair_cons => [[HR Hforall]].
  2177. apply: SeqForallPair_cons => //.
  2178. by apply: IH.
  2179. Qed.
  2180.  
  2181. Lemma SeqForallPair_iff A B (R: A -> B-> Prop) sa sb:
  2182. seq_forall_pair R sa sb <-> SeqForallPair R sa sb.
  2183. Proof.
  2184. split.
  2185. by apply: SeqForallPair_in_forall2.
  2186. by apply: SeqForallPair_in_forall1.
  2187. Qed.
  2188.  
  2189. Lemma SeqForallPair_ext1 A B (R1 R2: A -> B -> Prop) l1 l2:
  2190. (forall x y, R1 x y -> R2 x y) ->
  2191. SeqForallPair R1 l1 l2 ->
  2192. SeqForallPair R2 l1 l2.
  2193. Proof.
  2194. move => Hext.
  2195. elim => {l1 l2} => [|a b l1 l2 HRab Hforall12 IH12].
  2196. by apply: SeqForallPair_empty.
  2197. apply: SeqForallPair_cons => //.
  2198. by apply: Hext.
  2199. Qed.
  2200.  
  2201. Lemma SeqForallPair_ext A B (R1 R2: A -> B -> Prop) l1 l2:
  2202. (forall x y, R1 x y <-> R2 x y) ->
  2203. SeqForallPair R1 l1 l2 <->
  2204. SeqForallPair R2 l1 l2.
  2205. Proof.
  2206. move => Hext.
  2207. split;
  2208. apply: SeqForallPair_ext1 => x y;
  2209. by rewrite Hext.
  2210. Qed.
  2211.  
  2212. Lemma behead_rcons A (l: seq A) a b:
  2213. behead (rcons (rcons l a) b) = rcons (behead (rcons l a)) b.
  2214. Proof.
  2215. by elim: l a b => [|c l IH] a b.
  2216. Qed.
  2217.  
  2218. Lemma rev_behead A (l: seq A) a:
  2219. (rev (behead (rev (a :: l)))) ++ [:: (last a l)] = a::l.
  2220. Proof.
  2221. elim: l a => [|a' l IH] a //=.
  2222. rewrite !rev_cons behead_rcons.
  2223. rewrite rev_rcons -rev_cons /=.
  2224. by rewrite IH.
  2225. Qed.
  2226.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement