343343
344344lemma onth_some [' a] (xs : ' a list) (n : int) x:
345345 onth xs n = Some x => 0 <= n < size xs /\ nth witness xs n = x.
346- proof. by rewrite nth_onth => ^h -> /=; elim: xs n x h => //# . qed.
346+ proof. by rewrite nth_onth => ^h -> /=; elim: xs n x h => //=; smt(size_ge0) . qed.
347347
348348lemma onth_some_rg l n (x:' a): onth l n = Some x => 0 <= n < size l.
349349proof. by move/onth_some. qed.
@@ -819,6 +819,14 @@ lemma drop_cat n (s1 s2 : 'a list):
819819 if n < size s1 then drop n s1 ++ s2 else drop (n - size s1) s2.
820820proof. by elim: s1 n => /= [|x s ih] n; smt(drop_le0 size_ge0). qed.
821821
822+ lemma drop_cat_le [' a] (n : int ) (s1 s2 : ' a list) :
823+ drop n (s1 ++ s2) =
824+ if n <= size s1 then drop n s1 ++ s2 else drop (n - size s1) s2.
825+ proof.
826+ rewrite drop_cat lez_eqVlt; case: (n = size s1) => [->|] //=.
827+ by rewrite drop0 drop_size.
828+ qed.
829+
822830lemma drop_size_cat n (s1 s2 : ' a list):
823831 size s1 = n => drop n (s1 ++ s2) = s2.
824832proof. by move=> <-; rewrite drop_cat subzz ltzz drop0. qed.
@@ -858,7 +866,14 @@ proof. by rewrite /= lezNgt; case: (0 < n). qed.
858866
859867lemma size_take n (s : ' a list):
860868 0 <= n => size (take n s) = if n < size s then n else size s.
861- proof. by elim: s n => //= /#. qed.
869+ proof. by elim: s n => //=; smt(size_ge0). qed.
870+
871+ lemma size_take_condle [' a] (n : int ) (s : ' a list) :
872+ 0 <= n => size (take n s) = if n <= size s then n else size s.
873+ proof.
874+ move=> ge0_n; rewrite size_take // lez_eqVlt.
875+ by case: (n = size s) => [->|].
876+ qed.
862877
863878lemma size_takel n (s : ' a list ):
864879 0 <= n <= size s => size (take n s) = n.
@@ -879,6 +894,14 @@ lemma take_cat n (s1 s2 : 'a list):
879894 if n < size s1 then take n s1 else s1 ++ take (n - size s1) s2.
880895proof. by elim: s1 n => // =; smt(take_le0 size_ge0). qed.
881896
897+ lemma take_cat_le ['a] (n : int ) (s1 s2 : ' a list) :
898+ take n (s1 ++ s2) =
899+ if n <= size s1 then take n s1 else s1 ++ take (n - size s1) s2.
900+ proof.
901+ rewrite take_cat lez_eqVlt; case: (n = size s1) => [->|] //=.
902+ by rewrite take0 take_size cats0.
903+ qed.
904+
882905lemma take_size_cat n (s1 s2 : ' a list):
883906 size s1 = n => take n (s1 ++ s2) = s1.
884907proof. by move=> <-; rewrite take_cat subzz ltzz take0 cats0. qed.
@@ -891,7 +914,7 @@ by elim: n => [|n ge0_n _] /=; rewrite ?take0 //= /#.
891914qed.
892915
893916lemma cat_take_drop n (s : ' a list): take n s ++ drop n s = s.
894- proof. by elim: s n=>/#. qed.
917+ proof. by elim: s n=> /#. qed.
895918
896919lemma mem_drop n (s:' a list) x: mem (drop n s) x => mem s x.
897920proof. by rewrite -{2}[s](cat_take_drop n) mem_cat=>->. qed.
@@ -902,29 +925,40 @@ proof. by rewrite -{2}[s](cat_take_drop n) mem_cat=>->. qed.
902925lemma nth_drop (x0 : ' a) n s i:
903926 0 <= n => 0 <= i => nth x0 (drop n s) i = nth x0 s (n + i).
904927proof.
905- move=> n_ge0 i_ge0; case : (n < size s) => [lt_n_s|le_s_n]; last smt (nth_out drop_oversize).
906- rewrite -{2 }(cat_take_drop n s) nth_cat size_take // ; smt().
928+ move=> n_ge0 i_ge0; case: (n < size s) => [lt_n_s|le_s_n].
929+ - by rewrite -{2}(cat_take_drop n s) nth_cat size_take //#.
930+ - by rewrite !(nth_out, drop_oversize) //#.
907931qed.
908932
909933lemma nth_take (x0 : ' a) n s i:
910934 0 <= n => i < n => nth x0 (take n s) i = nth x0 s i.
911935proof.
912- move=> n_ge0 i_ge0; case: (n < size s) => [lt_n_s|le_s_n]; last smt(nth_out take_oversize).
913- by rewrite -{2}(cat_take_drop n s) nth_cat size_take //; smt().
936+ move=> n_ge0 i_ge0; case : (n < size s) => [lt_n_s|le_s_n].
937+ - by rewrite -{2 }(cat_take_drop n s) nth_cat size_take // #.
938+ - by rewrite take_oversize 1 :/#.
914939qed.
915940
916941lemma take_take (s : ' a list) (i j : int) :
917942 take i (take j s) = if i <= j then take i s else take j s.
918943proof. by elim: s i j => // /#. qed.
919944
945+ lemma cat_take_insert_drop [' a] (x0 : ' a) (n : int) (s : ' a list) :
946+ 0 <= n < size s => take n s ++ nth x0 s n :: drop (n+1 ) s = s.
947+ proof.
948+ case=> ge0_n lt_n_s; apply/eq_sym/(eq_from_nth x0).
949+ - by rewrite size_cat size_take -1 :lt_n_s // = size_drop //#.
950+ move=> i [ge0_i lti]; rewrite nth_cat size_take // = lt_n_s /=.
951+ smt (nth_take nth_drop).
952+ qed.
953+
920954lemma splitPr (xs : ' a list) (x : ' a): mem xs x =>
921955 exists s1, exists s2, xs = s1 ++ x :: s2.
922956proof.
923- move=> x_in_xs; pose i := index x xs.
924- have lt_ip: i < size xs by rewrite /i index_mem.
925- exists (take i xs); exists (drop (i+1 ) xs).
926- rewrite -{1 }(@cat_take_drop i) -(@nth_index x x xs) // .
927- by rewrite -drop_nth // index_ge0 lt_ip.
957+ move=> x_in_xs; pose i := index x xs.
958+ have lt_ip: i < size xs by rewrite /i index_mem.
959+ exists (take i xs); exists (drop (i+1 ) xs).
960+ rewrite -{1 }(@cat_take_drop i) -(@nth_index x x xs) // .
961+ by rewrite -drop_nth // index_ge0 lt_ip.
928962qed.
929963
930964(* -------------------------------------------------------------------- *)
@@ -1121,6 +1155,13 @@ elim: s => //= x s ih; case: (p x)=> @/predC -> //=;
11211155by rewrite perm_cons. by rewrite perm_cons.
11221156qed.
11231157
1158+ lemma perm_eq_nth_take_drop [' a] (x0 : ' a) (n : int) (s : ' a list) :
1159+ 0 <= n < size s => perm_eq (nth x0 s n :: take n s ++ drop (n + 1 ) s) s.
1160+ proof.
1161+ move=> rg; rewrite -cat1s perm_catCA -catA /= perm_eq_refl_eq.
1162+ by rewrite cat_take_insert_drop // perm_eq_refl.
1163+ qed.
1164+
11241165(* -------------------------------------------------------------------- *)
11251166(* Element removal *)
11261167(* -------------------------------------------------------------------- *)
@@ -1203,20 +1244,20 @@ qed.
12031244
12041245lemma perm_eqP_pred1 [' a] (s1 s2 : ' a list) : perm_eq s1 s2 <=> forall (x : ' a), count (pred1 x) s1 = count (pred1 x) s2.
12051246proof.
1206- rewrite perm_eqP; split => [Heq x|Heq p]; first by apply/Heq.
1207- elim s1 s2 Heq => [s2 /= Heq|hs1 ts1 IHs1 s2 /= Heq].
1208- + elim: s2 Heq => //= hs2 ts2 IHs2 Heq.
1209- move: (Heq hs2); rewrite /b2i /pred1 /= eqz_leq => -[_].
1210- by rewrite addrC -ltzE ltzNge count_ge0.
1211- move: IHs1 => /(_ (rem hs1 s2)) => ->.
1212- + move => x; move: (Heq hs1) (Heq x) => {Heq}.
1213- rewrite {1}/b2i {1}/pred1 /= => Heqhs1.
1214- rewrite (count_rem (pred1 x) s2 hs1); last by apply addrI.
1215- by rewrite mem_count -Heqhs1 addrC ltzS count_ge0.
1216- move: (Heq hs1) => {Heq}.
1247+ rewrite perm_eqP; split => [Heq x|Heq p]; first by apply/Heq.
1248+ elim s1 s2 Heq => [s2 /= Heq|hs1 ts1 IHs1 s2 /= Heq].
1249+ + elim: s2 Heq => //= hs2 ts2 IHs2 Heq.
1250+ move: (Heq hs2); rewrite /b2i /pred1 /= eqz_leq => -[_].
1251+ by rewrite addrC -ltzE ltzNge count_ge0.
1252+ move: IHs1 => /(_ (rem hs1 s2)) => ->.
1253+ + move => x; move: (Heq hs1) (Heq x) => {Heq}.
12171254 rewrite {1}/b2i {1}/pred1 /= => Heqhs1.
1218- rewrite (count_rem p s2 hs1) // .
1255+ rewrite (count_rem (pred1 x) s2 hs1); last by apply addrI .
12191256 by rewrite mem_count -Heqhs1 addrC ltzS count_ge0.
1257+ move: (Heq hs1) => {Heq}.
1258+ rewrite {1}/b2i {1}/pred1 /= => Heqhs1.
1259+ rewrite (count_rem p s2 hs1) //.
1260+ by rewrite mem_count -Heqhs1 addrC ltzS count_ge0.
12201261qed.
12211262
12221263(* -------------------------------------------------------------------- *)
@@ -1228,6 +1269,64 @@ op insert (x : 'a) (s : 'a list) (n : int) =
12281269op trim (xs : ' a list) (n : int ) =
12291270 take n xs ++ (drop (n+1 ) xs).
12301271
1272+ (* -------------------------------------------------------------------- *)
1273+ lemma size_insert ['a] (x : ' a) (s : ' a list) (n : int ) :
1274+ 0 <= n <= size s => size (insert x s n) = size s + 1.
1275+ proof.
1276+ move=> [ge0_n ltn] @/insert; rewrite size_cat /=.
1277+ by rewrite size_take // size_drop //#.
1278+ qed.
1279+
1280+ lemma nth_insert [' a] (x0 x : ' a) (s : ' a list) (n : int) :
1281+ 0 <= n <= size s => nth x0 (insert x s n) n = x.
1282+ proof. by move=> [ge0_n ltn] @/insert; rewrite nth_cat size_take //#. qed.
1283+
1284+ (* -------------------------------------------------------------------- *)
1285+ lemma mem_insert [' a] (x : ' a) (s : ' a list) (n : int ) (y : ' a) :
1286+ y \i n insert x s n => y = x \/ y \i n s.
1287+ proof.
1288+ rewrite /insert mem_cat /=; case.
1289+ - by move/mem_take=> ->.
1290+ - by case=> [->//|/mem_drop ->].
1291+ qed.
1292+
1293+ lemma insert_cat [' a] (x : ' a) (s1 s2 : ' a list) (n : int ) :
1294+ insert x (s1 ++ s2) n =
1295+ if n < size s1 then insert x s1 n ++ s2 else s1 ++ insert x s2 (n - size s1).
1296+ proof.
1297+ rewrite /insert take_cat drop_cat; case : (n < size s1) => /= _.
1298+ - by rewrite -cat_cons catA. - by rewrite catA.
1299+ qed.
1300+
1301+ lemma insert0 [' a] (x : ' a) (s : ' a list) : insert x s 0 = x :: s.
1302+ proof. by rewrite /insert take0 drop0 cat0s. qed.
1303+
1304+ hint simplify insert0.
1305+
1306+ lemma insert_nth_take_drop [' a] (x0 : ' a) (s : ' a list) (n : int ) :
1307+ 0 <= n < size s => insert (nth x0 s n) (take n s ++ drop (n + 1 ) s) n = s.
1308+ proof.
1309+ case=> ge0_n ltn; have sz_take: size (take n s) = n by rewrite size_take // ltn.
1310+ by rewrite insert_cat sz_take /= cat_take_insert_drop.
1311+ qed.
1312+
1313+ lemma take_insert_le [' a] (x : ' a) (s : ' a list) (i j : int) :
1314+ 0 <= i <= j <= size s => take i (insert x s j) = take i s.
1315+ proof.
1316+ move=> [# ge0_i le_ij le_js] @/insert; rewrite take_cat_le.
1317+ rewrite iftrue; first by rewrite size_take //#.
1318+ by rewrite take_take le_ij.
1319+ qed.
1320+
1321+ lemma drop_insert_gt [' a] (x : ' a) (s : ' a list) (i j : int ) :
1322+ 0 <= j < i <= size s + 1 => drop i (insert x s j) = drop (i - 1 ) s.
1323+ proof.
1324+ move=> [# ge0_j lt_ji le_i_Ss] @/insert; rewrite drop_cat.
1325+ rewrite iffalse; first by rewrite size_take // #.
1326+ rewrite size_take_condle // iftrue 1:/# drop_cons.
1327+ by rewrite iftrue 1 :/# drop_drop ~-1 :// #; congr => //#.
1328+ qed.
1329+
12311330(* -------------------------------------------------------------------- *)
12321331lemma trim_neg (xs : ' a list) (n : int): n < 0 => trim xs n = xs.
12331332proof. by move=> lt0_n; rewrite /trim take_le0 2:drop_le0 /#. qed.
0 commit comments