forked from mit-pdos/perennial
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathListSplice.v
90 lines (78 loc) · 2.24 KB
/
ListSplice.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
From stdpp Require Import list.
From Coq Require Import ssreflect.
From Perennial.Helpers Require Import ListLen.
Set Default Proof Using "Type".
Set Default Goal Selector "!".
Section list.
Context {A: Type}.
Implicit Types (l: list A) (x a: A) (n: nat).
(* list_splice is intended to be used with [n + length l' ≤ l], so that [l']
replaces elements of l. *)
Definition list_splice l n l' :=
take n l ++
(* we truncate l' so that the result is always the length of l without a
side condition; [list_splice_in_bounds] shows an equivalence to a simpler
definition that always inserts all of l'
*)
(take (Nat.min (length l') (length l - n)) l') ++
drop (n + length l') l.
Lemma list_splice_length l n l' :
length (list_splice l n l') = length l.
Proof.
rewrite /list_splice.
len.
Qed.
Lemma lookup_list_splice_old l n l' i :
¬(n ≤ i < n + length l') →
list_splice l n l' !! i = l !! i.
Proof.
intros.
rewrite /list_splice.
destruct (decide (i < length l)).
- destruct (decide (i < n)).
+ rewrite lookup_app_l; len.
rewrite lookup_take //.
+ rewrite lookup_app_r; len.
rewrite lookup_app_r; len.
rewrite lookup_drop //.
f_equal.
lia.
- rewrite !lookup_ge_None_2 //; len.
Qed.
Lemma lookup_list_splice_new l n l' i :
n + length l' ≤ length l →
n ≤ i < n + length l' →
list_splice l n l' !! i = l' !! (i - n).
Proof.
intros.
rewrite /list_splice.
rewrite lookup_app_r; len.
rewrite lookup_app_l; len.
rewrite lookup_take; len.
f_equal; lia.
Qed.
Lemma lookup_list_Some l n l' i x :
n + length l' ≤ length l →
list_splice l n l' !! i = Some x →
(n ≤ i < n + length l' ∧ l' !! (i - n) = Some x) ∨
((i < n ∨ i ≥ n + length l') ∧ l !! i = Some x).
Proof.
intros Hin_bounds.
destruct (decide (n ≤ i < n + length l')).
- rewrite lookup_list_splice_new //.
eauto.
- rewrite lookup_list_splice_old //.
intros.
right; split; auto. lia.
Qed.
Lemma list_splice_in_bounds l n l' :
n + length l' ≤ length l →
list_splice l n l' = take n l ++ l' ++ drop (n + length l') l.
Proof.
intros.
rewrite /list_splice.
rewrite Nat.min_l; [ lia | ].
rewrite (take_ge l') //.
Qed.
End list.
Hint Rewrite @list_splice_length using len : len.