Skip to content

Commit fe160c4

Browse files
authored
add new MSet theory (#722)
1 parent 04d4d4d commit fe160c4

6 files changed

Lines changed: 785 additions & 1 deletion

File tree

theories/algebra/Number.ec

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,15 @@ qed.
12911291
lemma maxrC (x y : t) : maxr x y = maxr y x.
12921292
proof. by rewrite !maxrE lerNgt ler_eqVlt; case: (x = y); case: (x < y). qed.
12931293

1294+
lemma maxrA (x y z: t): maxr (maxr x y) z = maxr x (maxr y z).
1295+
proof.
1296+
rewrite !maxrE.
1297+
case (y <= x); case (z <= y); case (z <= x) => //
1298+
[/#||/#|/#|].
1299+
- smt(ler_trans).
1300+
- smt(ltr_trans ltrNge).
1301+
qed.
1302+
12941303
lemma maxrl (x y : t) : x <= maxr x y.
12951304
proof. by rewrite maxrE; case: (y <= x) => [_|/ltrNge/ltrW]. qed.
12961305

@@ -1347,6 +1356,15 @@ qed.
13471356
lemma minrC (x y : t) : minr x y = minr y x.
13481357
proof. by rewrite !minrE lerNgt ler_eqVlt; case: (y = x); case: (y < x). qed.
13491358

1359+
lemma minrA (x y z: t): minr (minr x y) z = minr x (minr y z).
1360+
proof.
1361+
rewrite !minrE.
1362+
case (x <= y); case (y <= z); case (x <= z) => //
1363+
[/#||/#|/#|].
1364+
- smt(ler_trans).
1365+
- smt(ltr_trans ltrNge).
1366+
qed.
1367+
13501368
lemma minrl (x y : t) : minr x y <= x.
13511369
proof. by rewrite minrE; case: (x <= y) => [_|/ltrNge/ltrW]. qed.
13521370

theories/datatypes/FMap.ec

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ lemma remE ['a 'b] (m : ('a, 'b) fmap) x y :
200200
(rem m x).[y] = if y = x then None else m.[y].
201201
proof. by rewrite /rem /"_.[_]" rem_valE SmtMap.get_setE. qed.
202202
203+
lemma rem_set (m: ('a, 'b) fmap) x: x \in m => (rem m x).[x <- oget m.[x]] = m.
204+
proof. move => x_in; apply fmap_eqP => y; rewrite get_setE remE /#. qed.
205+
203206
(* -------------------------------------------------------------------- *)
204207
lemma mem_rem ['a 'b] (m : ('a, 'b) fmap) x y :
205208
y \in (rem m x) <=> (y \in m /\ y <> x).
@@ -529,6 +532,44 @@ lemma mem_fdom_rem ['a 'b] (m : ('a, 'b) fmap) x y :
529532
y \in fdom (rem m x) <=> (y \in fdom m /\ y <> x).
530533
proof. by rewrite fdom_rem in_fsetD1. qed.
531534

535+
(* ==================================================================== *)
536+
op offset (s: 'a fset): ('a, unit) fmap =
537+
ofmap (offun (fun e => if e \in s then Some () else None)).
538+
539+
lemma mem_offset (s: 'a fset) x: x \in (offset s) <=> x \in s.
540+
proof.
541+
rewrite /dom getE ofmapK.
542+
- move: (FSet.finite_mem s).
543+
apply/eq_ind/fun_ext => y.
544+
rewrite offunE /#.
545+
rewrite offunE /#.
546+
qed.
547+
548+
lemma offset_get s (e: 'a): (offset s).[e] = if e \in s then Some () else None.
549+
proof.
550+
rewrite getE /ofset ofmapK.
551+
- move: (FSet.finite_mem s).
552+
apply/eq_ind/fun_ext => y.
553+
rewrite offunE /#.
554+
rewrite offunE /#.
555+
qed.
556+
557+
lemma offsetK: cancel offset fdom<:'a, unit>.
558+
proof. move => s; rewrite fsetP => x; by rewrite mem_fdom mem_offset. qed.
559+
560+
(* ==================================================================== *)
561+
op offsetmap (f: 'a -> 'b) (s: 'a fset) : ('a, 'b) fmap =
562+
map (fun x y => f x) (offset s).
563+
564+
lemma offsetmapT (s: 'a fset) (f: 'a -> 'b) e: e \in s => (offsetmap f s).[e] = Some (f e).
565+
proof. by move => e_in; rewrite /offsetmap mapE offset_get e_in. qed.
566+
567+
lemma offsetmapN (s: 'a fset) (f: 'a -> 'b) e: e \notin s => (offsetmap f s).[e] = None.
568+
proof. by move => e_in; rewrite /offsetmap mapE offset_get e_in. qed.
569+
570+
lemma mem_offsetmap s (f: 'a -> 'b) e: e \in offsetmap f s <=> e \in s.
571+
proof. by rewrite /offsetmap mem_map mem_offset. qed.
572+
532573
(* ==================================================================== *)
533574
op [opaque] frng ['a 'b] (m : ('a, 'b) fmap) = oflist (to_seq (rng m)).
534575
lemma frngE (m : ('a, 'b) fmap): frng m = oflist (to_seq (rng m)).
@@ -741,6 +782,16 @@ lemma fsize_set (m : ('a, 'b) fmap) k v :
741782
fsize m.[k <- v] = b2i (k \notin m) + fsize m.
742783
proof. by rewrite /fsize fdom_set fcardU1 mem_fdom. qed.
743784
785+
lemma fsize0_empty (m: ('a, 'b) fmap): fsize m = 0 => m = empty.
786+
proof.
787+
move: m; apply fmapW => [//| /= m k v].
788+
rewrite mem_fdom fsize_set =>->_/=.
789+
smt(ge0_fsize).
790+
qed.
791+
792+
lemma fsize_map m (f: 'a -> 'b -> 'c): fsize (map f m) = fsize m.
793+
proof. by rewrite /fsize fdom_map. qed.
794+
744795
(* ==================================================================== *)
745796

746797
(* f-collisions (i.e. collisions under some function f) *)

theories/datatypes/FSet.ec

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(* -------------------------------------------------------------------- *)
2-
require import Core Int List StdRing StdOrder.
2+
require import Core Int List StdRing StdOrder Finite.
33
(*---*) import IntOrder.
44

55
(* -------------------------------------------------------------------- *)
@@ -84,6 +84,9 @@ split=> // h; apply/fset_eq/uniq_perm_eq; 1,2: exact/uniq_elems.
8484
by move=> x; rewrite -!memE h.
8585
qed.
8686
87+
lemma finite_mem (s: 'a fset): is_finite (mem s).
88+
proof. apply mkfinite; exists (elems s) => /#. qed.
89+
8790
(* -------------------------------------------------------------------- *)
8891
op [opaque] fset0 ['a] = oflist [<:'a>].
8992
lemma set0E: fset0<:'a> = oflist [<:'a>] by rewrite/fset0.

theories/datatypes/List.ec

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,14 @@ proof. by rewrite /nseq iter1. qed.
224224
lemma nseqS n (x : 'a) : 0 <= n => nseq (n+1) x = x :: nseq n x.
225225
proof. by move=> le0_n; rewrite /nseq iterS. qed.
226226

227+
lemma nseq_eq (x y: 'a) n m:
228+
nseq n x = nseq m y => (x = y /\ n = m) \/ (n <= 0 /\ m <= 0).
229+
proof.
230+
move => nseq_eq; have: max 0 n = max 0 m by smt(size_nseq).
231+
case (n <= 0) => [/#|]; case (m <= 0) => [/#|/=]/ltzNge mgt0/ltzNge ngt0 max_eq.
232+
move: nseq_eq; rewrite (nseqS (n-1)) 2:(nseqS (m-1)); smt(ltzW).
233+
qed.
234+
227235
lemma nseqSr n (x : 'a): 0 <= n => nseq (n+1) x = rcons (nseq n x) x.
228236
proof.
229237
elim: n=> /= [|i ge0_i ih]; first by rewrite nseq0 nseq1.
@@ -694,6 +702,13 @@ elim: s=> /= [|y s ih @/pred1]; first by rewrite nseq0.
694702
by case: (y = x)=> //; rewrite addzC nseqS ?count_ge0.
695703
qed.
696704

705+
lemma count_nseq (x: 'a) n p: count p (nseq n x) = if p x then max 0 n else 0.
706+
proof.
707+
move: n; apply natind => n n_bound /=.
708+
- rewrite nseq0_le //= /#.
709+
move => IH; rewrite nseqS //= lez_maxr /#.
710+
qed.
711+
697712
lemma has_nseq a n (x : 'a) : has a (nseq n x) <=> (0 < n) /\ a x.
698713
proof.
699714
elim/natind: n => /= [n ^le0_n /lezNgt->|n ge0_n]; 1: by rewrite nseq0_le.
@@ -1263,6 +1278,13 @@ qed.
12631278
lemma all_rem p (x : 'a) (s : 'a list): all p s => all p (rem x s).
12641279
proof. by move=> /allP h; apply/allP=> y /mem_rem /h. qed.
12651280
1281+
lemma count_remP ['a] (p : 'a -> bool) (s : 'a list) x :
1282+
count p (rem x s) = count p s - b2i (p x /\ x \in s).
1283+
proof.
1284+
case (x \in s) => [/perm_to_rem/perm_eqP/(_ p)->/#|x_in].
1285+
by rewrite rem_id.
1286+
qed.
1287+
12661288
lemma count_rem ['a] (p : 'a -> bool) (s : 'a list) x : x \in s =>
12671289
count p s = b2i (p x) + count p (rem x s).
12681290
proof. by move/perm_to_rem/perm_eqP/(_ p)=> ->. qed.

0 commit comments

Comments
 (0)