summaryrefslogtreecommitdiffstats
path: root/server/formal/period.v
diff options
context:
space:
mode:
authorRutger Broekhoff2026-08-28 18:03:05 +0200
committerRutger Broekhoff2026-08-28 18:03:05 +0200
commit973aec43ea54bbf95b64fbcb636403401d1ca60e (patch)
tree41b7911c420766a9b463245b9296f44c5bf35258 /server/formal/period.v
downloadroutemon-973aec43ea54bbf95b64fbcb636403401d1ca60e.tar.gz
routemon-973aec43ea54bbf95b64fbcb636403401d1ca60e.zip
Import from e4b104792206ee7ea64bf39c6b7d2c0c230f9d14
Diffstat (limited to 'server/formal/period.v')
-rw-r--r--server/formal/period.v828
1 files changed, 828 insertions, 0 deletions
diff --git a/server/formal/period.v b/server/formal/period.v
new file mode 100644
index 0000000..82921db
--- /dev/null
+++ b/server/formal/period.v
@@ -0,0 +1,828 @@
1From stdpp Require Import numbers option sorting ssreflect.
2From stdpp Require Import options.
3From routemon Require Import util.
4
5Definition timestamp := Z.
6Variant limit :=
7 | NegInftyLimit
8 | TsLimit (x : timestamp)
9 | PosInftyLimit.
10Instance limit_eq_dec : EqDecision limit.
11Proof. solve_decision. Qed.
12
13Notation "-∞" := NegInftyLimit.
14Notation "+∞" := PosInftyLimit.
15Coercion TsLimit : timestamp >-> limit.
16
17(* The interval [start, end). Considered empty when start >= end. *)
18Record period :=
19 Period
20 { period_start : limit
21 ; period_end : limit
22 }.
23Notation "'[' s ',' e ')'" := (Period s e).
24
25(* Consider making an inductive variant of these? *)
26Definition limit_le (l1 l2 : limit) :=
27 match l1, l2 with
28 | -∞, _ | _, +∞ => True
29 | TsLimit t1, TsLimit t2 => (t1 ≤ t2)%Z
30 | _, _ => False
31 end.
32Arguments limit_le !_ !_ / : assert.
33Definition limit_lt l1 l2 :=
34 match l1 with
35 | -∞ =>
36 match l2 with
37 | -∞ => False
38 | _ => True
39 end
40 | TsLimit t1 =>
41 match l2 with
42 | -∞ => False
43 | TsLimit t2 => (t1 < t2)%Z
44 | +∞ => True
45 end
46 | +∞ => False
47 end.
48Arguments limit_lt !_ !_ / : assert.
49Instance limit_le_dec : RelDecision limit_le.
50Proof. intros [] []; simpl; solve_decision. Qed.
51Instance limit_lt_dec : RelDecision limit_lt.
52Proof. intros [] []; simpl; solve_decision. Qed.
53Instance limit_lt_pi l1 l2 : ProofIrrel (limit_lt l1 l2).
54Proof. destruct l1, l2; apply _. Qed.
55
56Instance relation_equiv {A} : Equiv (relation A) :=
57 λ R1 R2, ∀ x y, R1 x y ↔ R2 x y.
58
59Lemma strict_limit_le_limit_lt :
60 strict limit_le ≡ limit_lt.
61Proof.
62 split.
63 - intros []. destruct x, y; simpl in *; try done. lia.
64 - intros H. destruct x, y; unfold strict; simpl in *; try done; auto with lia.
65Qed.
66
67Instance : Reflexive limit_le.
68Proof. intros l. by destruct l; simpl. Qed.
69Instance : Transitive limit_le.
70Proof. intros [] [] []; simpl; try done. lia. Qed.
71Instance : PreOrder limit_le.
72Proof. constructor; apply _. Qed.
73Instance : AntiSymm (=) limit_le.
74Proof.
75 intros [] []; simpl; try done.
76 intros H1 H2. f_equal. by apply Z.le_antisymm.
77Qed.
78Instance : PartialOrder limit_le.
79Proof. constructor; apply _. Qed.
80Instance : Trichotomy (strict limit_le).
81Proof with auto with lia.
82 intros [] []; unfold strict; simpl...
83 destruct (Z.lt_trichotomy x x0) as [H|[->|H]]...
84Qed.
85Instance : TotalOrder limit_le.
86Proof. constructor; apply _. Qed.
87
88Instance : StrictOrder (strict limit_le) := _.
89(* TODO: apparently useless??
90Instance rel_equiv_proper {A} (x y : A) : Proper ((≡) ==> (↔)) (λ R, R x y).
91Proof. easy. Qed.
92Search Proper iff eq.
93*)
94Instance complement_equiv {A} : Proper ((≡) ==> (≡)) (@complement A).
95Proof. intros R1 R2 HR12. split; unfold complement; intros Hequiv []%HR12%Hequiv. Qed.
96Instance Reflexive_equiv {A} : Proper ((≡) ==> (↔)) (@Reflexive A).
97Proof.
98 intros R1 R2 Hequiv. unfold Reflexive.
99 split; intros H x; by apply Hequiv.
100Qed.
101Instance Irreflexive_equiv {A} : Proper ((≡) ==> (↔)) (@Irreflexive A).
102Proof. unfold Irreflexive. by intros R1 R2 ->. Qed.
103Instance Transitive_equiv {A} : Proper ((≡) ==> (↔)) (@Transitive A).
104Proof.
105 intros R1 R2 Hequiv. unfold Transitive.
106 by split; intros H x y z Hxy%Hequiv Hyz%Hequiv; eapply Hequiv, H.
107Qed.
108Instance StrictOrder_equiv {A} : Proper ((≡) ==> (↔)) (@StrictOrder A).
109Proof.
110 intros R1 R2 Hequiv. split; intros [Hirr Htrans].
111 - by rewrite ->Hequiv in Hirr, Htrans.
112 - by rewrite <-Hequiv in Hirr, Htrans.
113Qed.
114Instance Trichotomy_equiv {A} : Proper ((≡) ==> (↔)) (@Trichotomy A).
115Proof.
116 intros R1 R2 Hequiv. split; intros.
117 - intros x y. by rewrite -(Hequiv x y) -(Hequiv y x).
118 - intros x y. by rewrite (Hequiv x y) (Hequiv y x).
119Qed.
120
121Instance : StrictOrder limit_lt.
122Proof. rewrite -strict_limit_le_limit_lt. apply _. Qed.
123Instance : Trichotomy limit_lt.
124Proof. rewrite -strict_limit_le_limit_lt. apply _. Qed.
125
126Definition limit_lt_ts' (l : limit) (t2 : timestamp) :=
127 match l with
128 | -∞ => True
129 | TsLimit t1 => (t1 < t2)%Z
130 | +∞ => False
131 end.
132Definition ts_le_limit' (t1 : timestamp) (l : limit) :=
133 match l with
134 | -∞ => False
135 | TsLimit t2 => (t1 ≤ t2)%Z
136 | +∞ => True
137 end.
138Lemma limit_lt_limit_lt_ts' l t2 : limit_lt_ts' l t2 ↔ limit_lt l t2.
139Proof. by destruct l. Qed.
140Lemma ts_le_limit'_limit_le t1 l : ts_le_limit' t1 l ↔ limit_le t1 l.
141Proof. by destruct l. Qed.
142
143Declare Scope limit_scope.
144Delimit Scope limit_scope with lim.
145Notation "l1 < l2" := (limit_lt l1 l2) : limit_scope.
146Notation "l1 ≤ l2" := (limit_le l1 l2) : limit_scope.
147Notation "l1 < l2 < l3" := (l1 < l2 ∧ l2 < l3)%lim : limit_scope.
148Notation "l1 ≤ l2 < l3" := (l1 ≤ l2 ∧ l2 < l3)%lim : limit_scope.
149Notation "l1 < l2 ≤ l3" := (l1 < l2 ∧ l2 ≤ l3)%lim : limit_scope.
150Notation "l1 ≤ l2 ≤ l3" := (l1 ≤ l2 ∧ l2 ≤ l3)%lim : limit_scope.
151Open Scope limit_scope.
152
153Instance period_elem_of : ElemOf timestamp period :=
154 λ t '[s, e), (s ≤ t < e).
155Instance period_elem_of_dec t (p : period) : Decision (t ∈ p).
156Proof. destruct p as [s e]. apply _. Qed.
157
158Lemma limit_le_lt l1 l2 : l1 < l2 ↔ l1 ≤ l2 ∧ l1 ≠ l2.
159Proof. by rewrite -(strict_limit_le_limit_lt l1 l2) strict_spec_alt. Qed.
160
161Lemma limit_le_cases {l1 l2} : l1 ≤ l2 ↔ l1 = l2 ∨ l1 < l2.
162Proof.
163 rewrite -(strict_limit_le_limit_lt l1 l2) strict_spec_alt. split.
164 - intros Hl12. destruct (decide (l1 = l2)) as [<-|Hne]; tauto.
165 - by intros [<-|[Hl12 _]].
166Qed.
167
168Lemma limit_lt_le_lt {l1} l2 {l3} : l1 ≤ l2 < l3 → l1 < l3.
169Proof. by intros [[<-|?]%limit_le_cases ?]; last etrans. Qed.
170
171Definition period_empty '[s, e) := e ≤ s.
172Definition period_empty_alt (p : period) := ∀ t, t ∉ p.
173Lemma period_empty_alt_iff p : period_empty p ↔ period_empty_alt p.
174Proof.
175 destruct p as [s e].
176 rewrite /period_empty /period_empty_alt /=.
177 split; intros H.
178 - intros t [contra []]%limit_lt_le_lt%limit_le_lt.
179 by eapply (anti_symm limit_le).
180 - destruct s as [|s|], e as [|e|]; try done.
181 + exfalso. apply (H (Z.pred e)). rewrite /elem_of /period_elem_of /=. lia.
182 + exfalso. by apply (H 0%Z).
183 + rewrite /elem_of /period_elem_of /= in H.
184 specialize (H s). simpl. lia.
185 + exfalso. apply (H s). rewrite /elem_of /period_elem_of /=. lia.
186Qed.
187Instance period_empty_dec p : Decision (period_empty p).
188Proof. destruct p as [s e]. solve_decision. Qed.
189
190Definition period_nonempty '[s, e) := s < e.
191Instance period_nonempty_dec p : Decision (period_nonempty p).
192Proof. destruct p. apply _. Qed.
193Instance period_nonempty_pi p : ProofIrrel (period_nonempty p).
194Proof. destruct p. apply _. Qed.
195
196Instance period_equiv : Equiv period :=
197 λ p1 p2, ∀ t, t ∈ p1 ↔ t ∈ p2.
198Instance period_equiv_reflexive : Reflexive period_equiv.
199Proof. done. Qed.
200Instance period_equiv_trans : Transitive period_equiv.
201Proof. intros p1 p2 p3 H1 H2 t. by rewrite H1. Qed.
202Instance period_equiv_symm : Symmetric period_equiv.
203Proof. by intros p1 p2 H t. Qed.
204Instance period_equiv_equiv : Equivalence period_equiv.
205Proof. constructor; apply _. Qed.
206
207(* All empty periods are equivalent *)
208Lemma period_empty_equiv p1 p2 : period_empty p1 → period_empty p2 ↔ p1 ≡ p2.
209Proof.
210 intros Hp1%period_empty_alt_iff. split.
211 - intros Hp2%period_empty_alt_iff. intros t.
212 split; [intros []%(Hp1 _) | intros []%(Hp2 _)].
213 - intros Hequiv. apply period_empty_alt_iff.
214 intros t []%Hequiv%(Hp1 _).
215Qed.
216
217Instance empty_period : Empty period := [TsLimit 0%Z, TsLimit 0%Z).
218Definition empty_period_empty : period_empty empty_period.
219Proof. done. Qed.
220
221Definition limit_min (l1 l2 : limit) := if decide (l1 ≤ l2) then l1 else l2.
222Definition limit_max (l1 l2 : limit) := if decide (l1 ≤ l2) then l2 else l1.
223
224Notation "l1 '`min`' l2" := (limit_min l1 l2) : limit_scope.
225Notation "l1 '`max`' l2" := (limit_max l1 l2) : limit_scope.
226
227Definition limit_min_ts (t1 t2 : timestamp) :
228 t1 `min` t2 = TsLimit (t1 `min` t2)%Z.
229Proof.
230 unfold limit_min.
231 destruct (decide (t1 ≤ t2));
232 simpl in *; f_equal; lia.
233Qed.
234
235Definition limit_max_ts (t1 t2 : timestamp) :
236 t1 `max` t2 = TsLimit (t1 `max` t2)%Z.
237Proof.
238 unfold limit_max.
239 destruct (decide (t1 ≤ t2));
240 simpl in *; f_equal; lia.
241Qed.
242
243Instance period_intersection : Intersection period := λ '[s1, e1) '[s2, e2),
244 [ s1 `max` s2, e1 `min` e2 ).
245
246Lemma intersect_and (p1 p2 : period) t :
247 t ∈ (p1 ∩ p2) ↔ t ∈ p1 ∧ t ∈ p2.
248Proof.
249 (* It really should be possible to optimize this proof somehow. *)
250 destruct p1 as [[|s1|] [|e1|]], p2 as [[|s2|] [|e2|]];
251 rewrite /intersection /period_intersection /elem_of /period_elem_of /limit_min /limit_max /limit_le /limit_lt /=;
252 repeat case_decide; tauto || lia.
253Qed.
254
255(* The points in time given by p1 except those given by p2, given as a before/after pair. *)
256Definition except '[s1, e1) '[s2, e2) : period * period :=
257 ( [ s1, e1 `min` s2 ),
258 [ s1 `max` e2, e1 ) ).
259
260Lemma limit_lt_ne l1 l2 : l1 < l2 → l1 ≠ l2.
261Proof. rewrite -(strict_limit_le_limit_lt l1 l2) strict_spec_alt. easy. Qed.
262
263Lemma not_limit_le l1 l2 : ¬ (l1 ≤ l2) ↔ l2 < l1.
264Proof.
265 destruct (trichotomy limit_lt l1 l2) as [Hl12|[<-|Hl21]].
266 - split; intros H.
267 + exfalso. apply H, limit_le_cases. by right.
268 + exfalso. by eapply asymmetry.
269 - split; intros H.
270 + exfalso. apply H, limit_le_cases. by left.
271 + by apply (_ : Irreflexive limit_lt) in H.
272 - split; intros H; first done.
273 intros [<-|Hl12]%limit_le_cases.
274 + by apply (_ : Irreflexive limit_lt) in H.
275 + by eapply asymmetry.
276Qed.
277
278Lemma not_limit_le' : complement limit_le ≡ flip limit_lt.
279Proof. apply: not_limit_le. Qed.
280
281Instance relation_equiv_reflexive {A} : Reflexive (@relation_equiv A).
282Proof. done. Qed.
283Instance relation_equiv_trans {A} : Transitive (@relation_equiv A).
284Proof. intros R1 R2 R3 H12 H23 x y. by rewrite H12 -H23. Qed.
285Instance relation_equiv_symm {A} : Symmetric (@relation_equiv A).
286Proof. by intros R1 R2 H12 x y. Qed.
287Instance relation_equiv_equiv {A} : Equivalence (@relation_equiv A).
288Proof. constructor; apply _. Qed.
289
290Lemma relation_flip_equiv {A} : Proper ((≡@{relation A}) ==> (≡)) flip.
291Proof. intros R1 R2 H12 x y. simpl. by rewrite (H12 y x). Qed.
292
293(* Could also be more generic *)
294Lemma relation_flip_involutive {A} (R : relation A) : flip (flip R) ≡ R.
295Proof. done. Qed.
296
297Lemma complement_involutive {A} `{!RelDecision (R : relation A)} : complement (complement R) ≡ R.
298Proof.
299 intros x y. split; intros Hxy.
300 - by destruct (decide (R x y)).
301 - by apply.
302Qed.
303
304Lemma not_limit_lt' : complement limit_lt ≡ flip limit_le.
305Proof.
306 rewrite -(relation_flip_involutive limit_lt) complement_inverse.
307 trans (flip (complement (complement limit_le))).
308 { apply relation_flip_equiv, complement_equiv, symmetry, not_limit_le'. }
309 apply relation_flip_equiv, complement_involutive.
310Qed.
311
312Lemma not_limit_lt l1 l2 : ¬ (l1 < l2) ↔ l2 ≤ l1.
313Proof. apply not_limit_lt'. Qed.
314
315(* TODO: make conclusion positive? *)
316Lemma period_nonempty_equiv_L_1 (s1 e1 s2 e2 : limit) :
317 period_nonempty [s1, e1) →
318 period_nonempty [s2, e2) →
319 [s1, e1) ≡ [s2, e2) →
320 ¬ s1 < s2.
321Proof.
322 unfold period_nonempty.
323 intros Hne1 Hne2 Hequiv Hs12.
324 destruct s2 as [|s2|]; [by destruct s1|..|by destruct s1].
325 destruct s1 as [|s1|]; last done.
326 * assert (Hs2a : s2 ∈ [s2, e2)).
327 { unfold elem_of, period_elem_of. by destruct e2. }
328 pose proof (proj2 (Hequiv s2) Hs2a) as [_ Hs2b].
329 assert (Hs2c : Z.pred s2 ∈ [-∞, e1)).
330 { unfold elem_of, period_elem_of.
331 by destruct e1 as [|e1|]; [|simpl in *; lia|]. }
332 pose proof (proj1 (Hequiv (Z.pred s2)) Hs2c) as [contra _].
333 simpl in contra. lia.
334 * assert (Hs1 : s1 ∈ [s1, e1)).
335 { unfold elem_of, period_elem_of. by destruct e1. }
336 pose proof (proj1 (Hequiv s1) Hs1) as [[Heq|Heq]%limit_le_cases _].
337 { rewrite Heq in Hs12. by eapply (_ : Irreflexive limit_lt). }
338 by eapply asymmetry.
339Qed.
340
341(* TODO: make conclusion positive? *)
342Lemma period_nonempty_equiv_L_2 (s1 e1 s2 e2 : limit) :
343 period_nonempty [s1, e1) →
344 period_nonempty [s2, e2) →
345 [s1, e1) ≡ [s2, e2) →
346 ¬ e1 < e2.
347Proof.
348 intros Hne1 Hne2 Hequiv He12.
349 destruct e1 as [|e1|]; [by destruct s1|..|done].
350 destruct e2 as [|e2|]; first done.
351 * (* e2 - 1 ∈ [s2, e2) → e2 - 1 ∈ [s1, e1) → s1 ≤ e2 - 1 < e1 → e2 ≤ e1 → e2 = e1 ∨ e2 < e1 *)
352 assert (He2a : Z.pred e2 ∈ [s2, e2)).
353 { unfold elem_of, period_elem_of.
354 by destruct s2 as [|s2|]; [simpl in *; lia..|]. }
355 pose proof (proj2 (Hequiv (Z.pred e2)) He2a) as [_ He2b].
356 simpl in *. lia.
357 * (* We want to plug e1 into the right side to get a
358 contradiction, so we need s2 ≤ e1. It suffices to show that
359 s2 ≤ e1 - 1 *)
360 assert (He1a : Z.pred e1 ∈ [s1, e1)).
361 { unfold elem_of, period_elem_of.
362 by destruct s1 as [|s1|]; [simpl in *; lia..|]. }
363 pose proof (proj1 (Hequiv (Z.pred e1)) He1a) as [He1b _].
364 assert (He1c : e1 ∈ [s2, +∞)).
365 { unfold elem_of, period_elem_of.
366 by destruct s2 as [|s2|]; [|simpl in *; lia|]. }
367 pose proof (proj2 (Hequiv e1) He1c) as [_ []%(_ : Irreflexive limit_lt)].
368Qed.
369
370Lemma period_nonempty_equiv_L p1 p2 :
371 period_nonempty p1 →
372 period_nonempty p2 →
373 p1 ≡ p2 → p1 = p2.
374Proof.
375 destruct p1 as [s1 e1], p2 as [s2 e2].
376 unfold equiv, period_equiv.
377 intros Hne1 Hne2 Hequiv.
378 f_equal.
379 - destruct (decide (s1 < s2)) as [Hs12|[<-|Hs21]%not_limit_lt%limit_le_cases]; [|done|].
380 + exfalso. by apply (period_nonempty_equiv_L_1 s1 e1 s2 e2).
381 + exfalso. by apply (period_nonempty_equiv_L_1 s2 e2 s1 e1).
382 - destruct (decide (e1 < e2)) as [He12|[<-|He21]%not_limit_lt%limit_le_cases]; [|done|].
383 + exfalso. by apply (period_nonempty_equiv_L_2 s1 e1 s2 e2).
384 + exfalso. by apply (period_nonempty_equiv_L_2 s2 e2 s1 e1).
385Qed.
386
387Definition period_empty_not_nonempty p : ¬ period_empty p ↔ period_nonempty p.
388Proof. destruct p. apply not_limit_le. Qed.
389
390Lemma limit_lt_min l1 l2 l3 :
391 l1 < l2 ∧ l1 < l3 ↔ l1 < l2 `min` l3.
392Proof.
393 split.
394 - intros [Hl12 Hl13]. unfold limit_min. by case_decide.
395 - unfold limit_min. intros H. case_decide.
396 + split; first done.
397 apply limit_le_cases in H0 as [<-|H0]; first done.
398 by etrans.
399 + apply not_limit_le in H0.
400 by split; first etrans.
401Qed.
402
403Lemma limit_max_le l1 l2 l3 :
404 l1 ≤ l3 ∧ l2 ≤ l3 ↔ l1 `max` l2 ≤ l3.
405Proof.
406 split.
407 - intros [Hl12 Hl23]. unfold limit_max. by case_decide.
408 - unfold limit_max. intros H. case_decide.
409 + by split; first etrans.
410 + apply not_limit_le in H0. split; first done.
411 apply limit_le_lt in H0 as [H0 _]. by etrans.
412Qed.
413Lemma limit_le_max l1 l2 l3 :
414 l1 ≤ l2 `max` l3 ↔ l1 ≤ l2 ∨ l1 ≤ l3.
415Proof.
416 unfold limit_max.
417 destruct (decide (l2 ≤ l3)) as [Hl23|Hl23%not_limit_le].
418 - split; first tauto. intros [H|H]; last done. by etrans.
419 - split; first tauto. intros [H|H]; first done.
420 by trans l3; last (apply limit_le_cases; right).
421Qed.
422
423Lemma except_lem p1 p2 t :
424 t ∈ p1 ∧ t ∉ p2 ↔
425 t ∈ (except p1 p2).1 ∨ t ∈ (except p1 p2).2.
426Proof.
427 destruct p1 as [s1 e1], p2 as [s2 e2]. split.
428 - intros [Hp1 Hp2].
429 (* on the left if t < s2, on the right if e2 ≤ t *)
430 destruct (decide (t < s2)) as [Hts2|Hts2].
431 + (* t < s2 *)
432 left. simpl. split.
433 * apply Hp1.
434 * apply limit_lt_min. split; last done.
435 rewrite /elem_of /period_elem_of in Hp1. easy.
436 + (* ¬ (t < s2) (↔ s2 ≤ t) *)
437 apply not_limit_lt in Hts2.
438 right. simpl. split.
439 * apply limit_max_le. split.
440 -- apply Hp1.
441 -- apply not_limit_lt. intros contra. by apply Hp2.
442 * apply Hp1.
443 - intros [H|H]; simpl in *.
444 + split.
445 * unfold elem_of, period_elem_of in *. split.
446 -- apply H.
447 -- by destruct H as [_ [H _]%limit_lt_min].
448 * unfold elem_of, period_elem_of in *.
449 destruct H as [H1 [H2 H3]%limit_lt_min].
450 intros [Hc1 Hc2].
451 apply limit_le_cases in Hc1 as [Hc1|Hc1].
452 -- inv Hc1. by apply (_ : Irreflexive limit_lt) in H3.
453 -- eapply asymmetry; [apply H3 | apply Hc1].
454 + unfold elem_of, period_elem_of in H.
455 rewrite -limit_max_le in H. destruct H as [[H1 H2] H3].
456 split; first done.
457 intros [Hc1 Hc2].
458 apply limit_le_cases in H2 as [H2|H2].
459 -- inv H2. by apply (_ : Irreflexive limit_lt) in Hc2.
460 -- eapply asymmetry; [apply H2 | apply Hc2].
461Qed.
462
463Lemma limit_max_lt l1 l2 l3 :
464 l1 `max` l2 < l3 ↔ l1 < l3 ∧ l2 < l3.
465Proof.
466 unfold limit_max.
467 destruct (decide (l1 ≤ l2)) as [Hl12|Hl12%not_limit_le].
468 - split; last easy. intros H. by split; first eapply limit_lt_le_lt.
469 - split; last easy. intros H. by split; last etrans.
470Qed.
471
472Lemma limit_min_lt l1 l2 l3 :
473 l1 `min` l2 < l3 ↔ l1 < l3 ∨ l2 < l3.
474Proof.
475 unfold limit_min.
476 destruct (decide (l1 ≤ l2)%lim) as [Hl12|Hl12%not_limit_le].
477 - split; first tauto. by intros [H|H]; last eapply limit_lt_le_lt.
478 - split; first tauto. by intros [H|H]; first etrans.
479Qed.
480
481Lemma limit_lt_max l1 l2 l3 :
482 l1 < l2 `max` l3 ↔ l1 < l2 ∨ l1 < l3.
483Proof.
484 unfold limit_max.
485 destruct (decide (l2 ≤ l3)) as [Hl23|Hl23%not_limit_le].
486 - split; first tauto. intros [H|H]; last done.
487 by apply limit_le_cases in Hl23 as [<-|Hl23]; last etrans.
488 - split; first tauto. by intros [H|H]; last etrans.
489Qed.
490
491Instance limit_min_comm : Comm (=) limit_min.
492Proof.
493 unfold limit_min.
494 intros [] []; repeat case_decide;
495 try done; simpl in *; f_equal; lia.
496Qed.
497Instance limit_max_comm : Comm (=) limit_max.
498Proof.
499 unfold limit_max.
500 intros [] []; repeat case_decide;
501 try done; simpl in *; f_equal; lia.
502Qed.
503
504Lemma limit_max_eq_l l1 l2 : l1 `max` l2 = l1 ↔ l2 ≤ l1.
505Proof.
506 unfold limit_max. case_decide; split.
507 - by intros ->.
508 - intros H12. by eapply (_ : AntiSymm (=) limit_le).
509 - intros _. apply limit_le_cases. right.
510 by apply not_limit_le.
511 - by intros _.
512Qed.
513Lemma limit_max_eq_r l1 l2 : l1 `max` l2 = l2 ↔ l1 ≤ l2.
514Proof. rewrite [l1 `max` l2]comm. apply limit_max_eq_l. Qed.
515
516Lemma limit_max_l l1 l2 : l2 ≤ l1 → l1 `max` l2 = l1.
517Proof. apply limit_max_eq_l. Qed.
518Lemma limit_max_r l1 l2 : l1 ≤ l2 → l1 `max` l2 = l2.
519Proof. apply limit_max_eq_r. Qed.
520
521Definition ne_period := { p : period | period_nonempty p }.
522
523Instance ne_period_elem_of : ElemOf timestamp ne_period :=
524 λ t p, t ∈ `p.
525Instance ne_period_elem_of_dec t (p : ne_period) : Decision (t ∈ p).
526Proof. apply _. Qed.
527
528(* TODO: rename to ne_period_before *)
529Definition period_before '([s1, e1) ↾ _ : ne_period) '([s2, e2) ↾ _ : ne_period) :=
530 e1 < s2.
531
532Instance period_before_pi p1 p2 : ProofIrrel (period_before p1 p2).
533Proof. destruct p1 as [[s1 e1] Hne1], p2 as [[s2 e2] Hne2]. apply _. Qed.
534
535Instance period_before_trans : Transitive period_before.
536Proof.
537 intros [[s1 e1] Hne1] [[s2 e2] Hne2] [[s3 e3] Hne3] H1 H2.
538 unfold period_before in *. simpl in *.
539 by trans s2; last trans e2.
540Qed.
541
542Instance period_before_irrefl : Irreflexive period_before.
543Proof.
544 intros [[s e] Hne] Hp. simpl in *.
545 eapply (_ : Irreflexive limit_lt). by etrans.
546Qed.
547
548Instance period_before_strict_order : StrictOrder period_before.
549Proof. split; apply _. Qed.
550
551Definition ne_period_rel (R : relation ne_period) : relation period :=
552 λ p1 p2, ∃ H1 H2, R (p1 ↾ H1) (p2 ↾ H2).
553
554Instance ne_period_rel_trans `{!Transitive R} : Transitive (ne_period_rel R).
555Proof.
556 intros p1 p2 p3 (H1 & H2 & HR12) (H2' & H3 & HR23).
557 exists H1, H3. replace H2' with H2 in HR23; last apply proof_irrel.
558 by etrans.
559Qed.
560
561Instance ne_period_rel_irrefl `{!Irreflexive R} : Irreflexive (ne_period_rel R).
562Proof.
563 intros p. intros (H1 & H2 & HR).
564 replace H2 with H1 in HR; last apply proof_irrel.
565 by apply (_ : Irreflexive R) in HR.
566Qed.
567
568Instance ne_period_rel_pi (R : relation ne_period) `{!∀ x y, ProofIrrel (R x y)} x y :
569 ProofIrrel (ne_period_rel R x y).
570Proof. apply _. Qed.
571
572Lemma except_parts_order p1 p2 :
573 period_nonempty p2 →
574 period_nonempty (except p1 p2).1 →
575 period_nonempty (except p1 p2).2 →
576 ne_period_rel period_before (except p1 p2).1 (except p1 p2).2.
577Proof.
578 destruct p1 as [s1 e1], p2 as [s2 e2]. simpl. intros H0 Hne1 Hne2.
579 unfold period_before. split; [done|split; [done|]].
580 apply limit_min_lt. right. apply limit_lt_max. right. apply H0.
581Qed.
582
583Definition period_nonempty_alt (p : period) := ∃ t, t ∈ p.
584
585Lemma period_nonempty_alt_iff p :
586 period_nonempty p ↔ period_nonempty_alt p.
587Proof.
588 unfold period_nonempty, period_nonempty_alt.
589 destruct p as [s e]. split.
590 - intros Hlt. destruct s as [|s|]; last done.
591 + destruct e as [|e|]; first done.
592 * exists (Z.pred e). by split; last (simpl; lia).
593 * exists 0%Z. done.
594 + exists s. done.
595 - intros [t Ht]. by eapply limit_lt_le_lt.
596Qed.
597
598Instance period_eq_dec : EqDecision period.
599Proof. solve_decision. Qed.
600
601Instance period_disjoint : Disjoint period :=
602 λ p1 p2, period_empty (p1 ∩ p2).
603
604Instance period_intersection_comm : Comm (=) period_intersection.
605Proof.
606 intros [s1 e1] [s2 e2].
607 by rewrite /= [s2 `max` s1]comm [e2 `min` e1]comm.
608Qed.
609Instance period_disjoint_symm : Symmetric period_disjoint.
610Proof. intros p1 p2. unfold period_disjoint. by rewrite comm. Qed.
611
612Lemma limit_min_eq_l l1 l2 : l1 `min` l2 = l1 ↔ l1 ≤ l2.
613Proof.
614 unfold limit_min. case_decide; first done. split.
615 - intros ->. exfalso. by apply H.
616 - intros []%H.
617Qed.
618Lemma limit_min_eq_r l1 l2 : l1 `min` l2 = l2 ↔ l2 ≤ l1.
619Proof. rewrite [l1 `min` l2]comm. apply limit_min_eq_l. Qed.
620
621Lemma limit_min_l l1 l2 : l1 ≤ l2 → l1 `min` l2 = l1.
622Proof. apply limit_min_eq_l. Qed.
623Lemma limit_min_r l1 l2 : l2 ≤ l1 → l1 `min` l2 = l2.
624Proof. apply limit_min_eq_r. Qed.
625
626Lemma limit_lt_le_trans {l1} l2 {l3} : l1 < l2 → l2 ≤ l3 → l1 < l3.
627Proof. by intros Hlt12 [->|Hlt23]%limit_le_cases; last etrans. Qed.
628
629Instance period_union : Union period :=
630 λ '[s1, e1) '[s2, e2), [s1 `min` s2, e1 `max` e2).
631
632Lemma limit_min_le l1 l2 l3 :
633 l1 ≤ l3 ∨ l2 ≤ l3 ↔
634 l1 `min` l2 ≤ l3.
635Proof.
636 unfold limit_min. case_decide; split.
637 - by intros [H13|H23]; last trans l2.
638 - intros H13. by left.
639 - apply not_limit_le in H. intros [H13|H23]; last done.
640 trans l1; last done.
641 apply limit_le_cases. by right.
642 - intros H23. by right.
643Qed.
644
645Lemma limit_le_min l1 l2 l3 :
646 l1 ≤ l2 ∧ l1 ≤ l3 ↔
647 l1 ≤ l2 `min` l3.
648Proof.
649 unfold limit_min. case_decide; split.
650 - by intros [H12 _].
651 - intros ?. by split; last trans l2.
652 - by intros [_ H13].
653 - intros ?. split; last done.
654 apply not_limit_le in H.
655 trans l3; first done.
656 apply limit_le_cases. by right.
657Qed.
658
659Lemma period_union_lem_1 t (p1 p2 : period) :
660 t ∈ p1 ∨ t ∈ p2 → t ∈ p1 ∪ p2.
661Proof.
662 destruct p1 as [s1 e1], p2 as [s2 e2].
663 unfold union, period_union.
664 intros [Ht|Ht]; split.
665 - apply limit_min_le. left. apply Ht.
666 - apply limit_lt_max. left. apply Ht.
667 - apply limit_min_le. right. apply Ht.
668 - apply limit_lt_max. right. apply Ht.
669Qed.
670
671Definition unifiable '[s1, e1) '[s2, e2) :=
672 s2 ≤ e1 ∧ s1 ≤ e2.
673
674Instance unifiable_dec : RelDecision unifiable.
675Proof. intros [] []. solve_decision. Qed.
676
677Lemma not_limit_le_lt l1 l2 l3 :
678 ¬ l1 ≤ l2 < l3 ↔ l2 < l1 ∨ l3 ≤ l2.
679Proof.
680 split.
681 - intros H123.
682 destruct (decide (l2 < l1)) as [?|H21%not_limit_lt]; first by left.
683 destruct (decide (l3 ≤ l2)) as [?|H32%not_limit_le]; first by right.
684 exfalso. by apply H123.
685 - intros [H21|H32] contra.
686 + eapply not_limit_le; [apply H21|apply contra].
687 + eapply not_limit_lt; [apply H32|apply contra].
688Qed.
689
690Lemma limit_lt_le l1 l2 : l1 < l2 → l1 ≤ l2.
691Proof. intros Hlt. apply limit_le_cases. by right. Qed.
692
693Lemma period_union_lem_2 t (p1 p2 : period) :
694 unifiable p1 p2 →
695 t ∈ p1 ∪ p2 → t ∈ p1 ∨ t ∈ p2.
696Proof.
697 intros Hunif Hunion.
698 destruct (decide (t ∈ p1)) as [?|Ht1]; first by left.
699 destruct (decide (t ∈ p2)) as [?|Ht2]; first by right.
700 exfalso.
701
702 destruct p1 as [s1 e1], p2 as [s2 e2].
703 unfold elem_of, period_elem_of in *.
704 simpl in *. destruct Hunif as [Hunif1 Hunif2].
705
706 (* If t is not in p1, then it must be in p2 *)
707 apply Ht2. clear Ht2.
708 apply not_limit_le_lt in Ht1.
709 destruct Ht1 as [Ht1|Ht1].
710 - (* t is not in p1 because it is before p1 (where p2 must hence be) *)
711 destruct Hunion as [Hunion1 Hunion2].
712 apply limit_min_le in Hunion1 as [[->|contra]%limit_le_cases | Hunion1].
713 { exfalso. by eapply (_ : Irreflexive limit_lt). }
714 { exfalso. by eapply (asymmetry (R:=limit_lt)). }
715 split; first done. by eapply limit_lt_le_trans.
716 - destruct Hunion as [Hunion1 Hunion2].
717 apply limit_lt_max in Hunion2 as [Hunion2 | Hunion2].
718 + apply limit_le_cases in Ht1 as [->|contra].
719 { exfalso. by eapply (_ : Irreflexive limit_lt). }
720 { exfalso. by eapply (asymmetry (R:=limit_lt)). }
721 + split; last done. by trans e1.
722Qed.
723
724Instance period_union_comm : Comm (=) period_union.
725Proof.
726 unfold period_union. intros [s1 e1] [s2 e2].
727 by rewrite limit_min_comm limit_max_comm.
728Qed.
729
730Instance period_singleton : Singleton timestamp period :=
731 λ t, [t, TsLimit (Z.succ t)).
732Lemma period_singleton_lem_1 t : t ∈ ({[t]} : period).
733Proof. by split; simpl; last lia. Qed.
734Lemma period_singleton_lem_2 t t' : t' ∈ ({[t]} : period) → t' = t.
735Proof.
736 unfold singleton, period_singleton.
737 intros [H11 H12]. destruct t, t'; try done; simpl in *; lia.
738Qed.
739Lemma period_singleton_nonempty t : period_nonempty {[t]}.
740Proof.
741 apply period_nonempty_alt_iff.
742 exists t. apply period_singleton_lem_1.
743Qed.
744
745Lemma unifiable_period_union p1 p2 p3 :
746 unifiable p1 p2 → unifiable p2 p3 →
747 unifiable (p1 ∪ p2) p3.
748Proof.
749 destruct p1 as [s1 e1], p2 as [s2 e2], p3 as [s3 e3].
750 intros [Hunif11 Hunif12] [Hunif21 Hunif22]. simpl. split.
751 + apply limit_le_max. by right.
752 + apply limit_min_le. by right.
753Qed.
754
755Instance unifiable_symm : Symmetric unifiable.
756Proof. by intros [] [] []. Qed.
757
758Definition Σlift {A} {Φ : A → Prop} (R : relation A) : relation {x : A | Φ x} :=
759 λ '(x↾_) '(y↾_), R x y.
760
761Instance Σlift_symm {A Φ} `{!Symmetric R} : Symmetric (@Σlift A Φ R).
762Proof. intros [x Hx] [y Hy] HR. simpl in *. by apply symmetry. Qed.
763
764(* TODO: probably unused? *)
765Instance Σlift_dec {A Φ} `{!RelDecision R} : RelDecision (@Σlift A Φ R).
766Proof. intros [x Hx] [y Hy]. by simpl. Qed.
767
768Definition ne_period_unifiable : relation ne_period := Σlift unifiable.
769
770Lemma period_unifiable_not_before p1 p2 : ne_period_unifiable p1 p2 → ¬ period_before p1 p2.
771Proof.
772 destruct p1 as [[s1 e1] Hne1], p2 as [[s2 e2] Hne2]. simpl in *.
773 intros [Hunif1 Hunif2] Hbefore.
774 apply limit_le_cases in Hunif1 as [->|contra].
775 - by eapply (_ : Irreflexive limit_lt).
776 - by eapply (asymmetry (R:=limit_lt)).
777Qed.
778
779(* TODO: define total relation on Σperiod_nonempty, p1 p2 := unifiable p1 p2 ∨ p1 < p2.
780 (Then have [AntiSymm unifiable (≤@{Σperiod_nonempty})].)
781 Show decidability, perform mergesort.
782 Then make the rest of normalization consist in unification of the periods.
783 *)
784
785Definition ne_period_le p1 p2 := ne_period_unifiable p1 p2 ∨ period_before p1 p2.
786
787Instance ne_period_le_antisymm : AntiSymm ne_period_unifiable ne_period_le.
788Proof.
789 intros p1 p2 [H12|H12] [H21|H21]; [done|done|..].
790 - exfalso. apply symmetry in H21.
791 by eapply period_unifiable_not_before.
792 - exfalso. by eapply asymmetry.
793Qed.
794
795Lemma ne_period_neither_before_unifiable p1 p2 :
796 ¬ period_before p1 p2 → ¬ period_before p2 p1 →
797 ne_period_unifiable p1 p2.
798Proof.
799 destruct p1 as [[s1 e1] Hne1], p2 as [[s2 e2] Hne2].
800 simpl in *. by intros ?%not_limit_lt ?%not_limit_lt.
801Qed.
802
803Instance period_before_dec : RelDecision period_before.
804Proof.
805 intros [[s1 e1] ?] [[s2 e2] ?]. simpl in *.
806 solve_decision.
807Qed.
808
809Lemma ne_period_not_unifiable p1 p2 :
810 ¬ ne_period_unifiable p1 p2 →
811 period_before p1 p2 ∨ period_before p2 p1.
812Proof.
813 intros Hnunif.
814 destruct (decide (period_before p1 p2)) as [?|H12]; first by left.
815 destruct (decide (period_before p2 p1)) as [?|H21]; first by right.
816 exfalso. by apply Hnunif, ne_period_neither_before_unifiable.
817Qed.
818
819Instance ne_period_le_total : Total ne_period_le.
820Proof.
821 intros p1 p2.
822 destruct (decide (ne_period_unifiable p1 p2)) as [Hunif|Hnunif].
823 - (* which one we pick does not matter *)
824 by do 2 left.
825 - apply ne_period_not_unifiable in Hnunif as [H12|H21].
826 + left. by right.
827 + right. by right.
828Qed.