File: FsetInt.v

package info (click to toggle)
why3 1.8.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 45,028 kB
  • sloc: xml: 185,443; ml: 111,224; ansic: 3,998; sh: 2,578; makefile: 2,568; java: 865; python: 720; javascript: 290; lisp: 205; pascal: 173
file content (270 lines) | stat: -rw-r--r-- 8,204 bytes parent folder | download
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
(********************************************************************)
(*                                                                  *)
(*  The Why3 Verification Platform   /   The Why3 Development Team  *)
(*  Copyright 2010-2025 --  Inria - CNRS - Paris-Saclay University  *)
(*                                                                  *)
(*  This software is distributed under the terms of the GNU Lesser  *)
(*  General Public License version 2.1, with the special exception  *)
(*  on linking described in file LICENSE.                           *)
(********************************************************************)

(* This file is generated by Why3's Coq-realize driver *)
(* Beware! Only edit allowed sections below    *)
Require Import BuiltIn.
Require BuiltIn.
Require HighOrd.
Require int.Int.
Require set.Fset.

Require Import Lia.

(* Why3 goal *)
Definition min_elt : set.Fset.fset Numbers.BinNums.Z -> Numbers.BinNums.Z.
Proof.
intros.
destruct X as (fs, H).
(* We use the list to define the algorithm *)
eapply ClassicalEpsilon.constructive_indefinite_description in H.
destruct H as (l, Hl).
destruct l.
- apply Z.zero. (* If the list is empty the result is unspecified *)
- apply (List.fold_left (fun acc x => if Z_le_dec acc x then acc else x) l z).
Defined.

(* Why3 goal *)
Lemma min_elt_def :
  forall (s:set.Fset.fset Numbers.BinNums.Z), ~ set.Fset.is_empty s ->
  set.Fset.mem (min_elt s) s /\
  (forall (x:Numbers.BinNums.Z), set.Fset.mem x s -> ((min_elt s) <= x)%Z).
Proof.
intros s h1.
unfold min_elt, Fset.is_empty, Fset.mem, set.Set.mem in *. 
destruct s. simpl.
destruct ClassicalEpsilon.constructive_indefinite_description as [l [Hdupl Heql]].
destruct l.
{ destruct h1. intros. intro. apply Heql in H. destruct H. }
assert (forall l z,
  forall x, List.In x l -> List.fold_left (fun x1 acc : int => if Z_le_dec x1 acc then x1 else acc) l z <= x)%Z.
{
induction l0; intros.
{ destruct H. }
assert (forall l z, List.fold_left (fun x1 acc : int => if Z_le_dec x1 acc then x1 else acc) l z <= z)%Z.
{
  induction l1; intros; simpl; eauto. lia.
  simpl. destruct Z_le_dec. eauto. eapply Z.le_trans with a0; eauto. lia.
}
simpl. destruct Z_le_dec.
destruct (Z_le_dec z0 x0).
eapply Z.le_trans with z0. eapply H0. assumption.
simpl in H. destruct H.  subst. lia.
eapply IHl0; eauto.

destruct (Z_le_dec a x0).
eapply Z.le_trans with a. eapply H0. assumption.
simpl in H. destruct H. subst. lia.
eapply IHl0; eauto.
}

assert (forall l z, List.In (List.fold_left (fun x acc => if Z_le_dec x acc then x else acc) l z) l \/
  List.fold_left (fun x acc => if Z_le_dec x acc then x else acc) l z = z).
{
  induction l0; intros.
  + simpl. right. reflexivity.
  + simpl. destruct Z_le_dec.
    - specialize (IHl0 z0). intuition.
    - specialize (IHl0 a). intuition.
}

split.
rewrite <- Heql. simpl. specialize (H0 l z). intuition.

intros. eapply Heql in H1. eapply (H (List.cons z l) z) in H1; eauto. simpl in H1.
destruct Z_le_dec. assumption.
lia.
Qed.

(* Why3 goal *)
Definition max_elt : set.Fset.fset Numbers.BinNums.Z -> Numbers.BinNums.Z.
Proof.
intros.
apply (- min_elt (Fset.map (fun x => - x) X))%Z.
Defined.

(* Why3 goal *)
Lemma max_elt_def :
  forall (s:set.Fset.fset Numbers.BinNums.Z), ~ set.Fset.is_empty s ->
  set.Fset.mem (max_elt s) s /\
  (forall (x:Numbers.BinNums.Z), set.Fset.mem x s -> (x <= (max_elt s))%Z).
Proof.
intros s h1.
unfold max_elt.
assert (~ Fset.is_empty (Fset.map (fun x : int => (- x)%Z) s))%Z.
{ unfold Fset.is_empty in *.
intro. destruct h1. intros. intro. specialize (H (-x)%Z).
apply H. eapply Fset.mem_map. assumption.
}
specialize (min_elt_def (Fset.map (fun x => -x)%Z s) H).
intros. destruct H0.
split.
clear H1 H h1.
rewrite Fset.map_def in H0. destruct H0.
destruct H. rewrite H0. replace ( - - x)%Z with x. assumption.
ring.

intros. clear H0. clear h1 H.
assert (min_elt (Fset.map (fun x => - x) s) <= -x)%Z.
{
  eapply H1; eauto. apply Fset.mem_map. assumption.
}
lia.
Qed.

Fixpoint seqZ l len : list Numbers.BinNums.Z :=
  match len with
  | S n => List.cons l (seqZ (l + 1)%Z n)
  | O => List.nil
  end.

Lemma seqZ_le: forall len x l, List.In x (seqZ l len) -> (l <= x)%Z.
Proof.
induction len; simpl; intuition.
eapply IHlen in H0; intuition.
Qed.

Lemma seqZ_le2: forall len x l, List.In x (seqZ l len) -> (x < l + Z.of_nat len)%Z.
Proof.
induction len; simpl; intuition idtac.
- subst. lia.
- eapply IHlen in H0. lia.
Qed.

Lemma seqZ_rev: forall len x l, (l <= x < l + Z.of_nat len)%Z -> List.In x (seqZ l len).
Proof.
induction len; intros; simpl in *.
+ lia.
+ destruct (Z.eq_dec l x); eauto.
  right. eapply IHlen; eauto. lia.
Qed.

Lemma seqZ_In_iff: forall l len x, List.In x (seqZ l len) <-> (l <= x <  l + Z.of_nat len)%Z.
Proof.
split.
intros. eauto using seqZ_le, seqZ_le2.
eapply seqZ_rev.
Qed.

Lemma seqZ_NoDup: forall len l, List.NoDup (seqZ l len).
Proof.
induction len; intros.
+ constructor.
+ simpl. constructor; eauto.
  intro Habs. eapply seqZ_le in Habs. lia.
Qed.

Lemma seqZ_length: forall len l, List.length (seqZ l len) = len.
Proof.
induction len; eauto.
intros. simpl. rewrite IHlen. reflexivity.
Qed.

Lemma interval_proof :
  forall l r : int, exists s : list int,
  List.NoDup s /\
  forall e : int, List.In e s <->
   (if Z_le_dec l e then if Z_lt_dec e r then true else false else false) = true.
Proof.
intros l r.
destruct (Z_le_dec l r).
+ exists (seqZ l (Z.to_nat (r - l))%Z).
  split. 
  - eapply seqZ_NoDup.
  - intros.
    rewrite seqZ_In_iff.
    rewrite Z2Nat.id; [|lia].
    destruct Z_le_dec.
    * destruct Z_lt_dec. split; intros; [reflexivity|].
      intuition.
      intuition ; try inversion H.
    * intuition ; try inversion H.
+ exists List.nil. 
  split.
  - constructor.
  - intros.
    destruct Z_le_dec; try destruct Z_lt_dec; intuition.
    lia.
    inversion H.
    inversion H.
Qed.

(* Why3 goal *)
Definition interval :
  Numbers.BinNums.Z -> Numbers.BinNums.Z -> set.Fset.fset Numbers.BinNums.Z.
Proof.
intros l r.
exists (fun x =>
  if Z_le_dec l x then
    if Z_lt_dec x r then true else false
  else false).
apply interval_proof.
Defined.

(* Why3 goal *)
Lemma interval_def :
  forall (l:Numbers.BinNums.Z) (r:Numbers.BinNums.Z) (x:Numbers.BinNums.Z),
  set.Fset.mem x (interval l r) <-> (l <= x)%Z /\ (x < r)%Z.
Proof.
intros l r x.
unfold interval, Fset.mem, set.Set.mem.
destruct Z_le_dec; try destruct Z_lt_dec; intuition; try inversion H.
Qed.

Lemma interval_is_finite: forall l r, 
  Cardinal.is_finite (fun x : int => 
    if Z_le_dec l x then if Z_lt_dec x r then true 
    else false else false).
Proof.
intros. 
unfold Cardinal.is_finite.
destruct (Z_le_dec l r).
+ exists (seqZ l (Z.to_nat (r - l)%Z)).
  split. apply seqZ_NoDup.
  intros. rewrite seqZ_In_iff.
  rewrite Z2Nat.id; [|lia].
  destruct Z_le_dec; try destruct Z_lt_dec; intuition; try inversion H.
+ exists nil. split. constructor.
  simpl. intros. destruct Z_le_dec; try destruct Z_lt_dec; intuition.
Qed.


(* Why3 goal *)
Lemma cardinal_interval :
  forall (l:Numbers.BinNums.Z) (r:Numbers.BinNums.Z),
  ((l <= r)%Z -> ((set.Fset.cardinal (interval l r)) = (r - l)%Z)) /\
  (~ (l <= r)%Z -> ((set.Fset.cardinal (interval l r)) = 0%Z)).
Proof.
intros l r.
unfold interval, Fset.mem, set.Set.mem, Fset.cardinal, Cardinal.cardinal.
assert (H := interval_is_finite l r).
destruct ClassicalEpsilon.excluded_middle_informative; [| intuition]. 
destruct ClassicalEpsilon.classical_indefinite_description.
specialize (a i).
split.
+ intros.
  destruct a. 
  assert (length (seqZ l (Z.to_nat (r - l)%Z)) = length x).
  {
    eapply Nat.le_antisymm.
    + eapply List.NoDup_incl_length. eapply seqZ_NoDup. intro. rewrite H2.
      rewrite seqZ_In_iff. destruct Z_le_dec; try destruct Z_lt_dec; intuition idtac.
      rewrite Z2Nat.id in H5; lia.
    + eapply List.NoDup_incl_length. assumption. intro. rewrite H2.
      rewrite seqZ_In_iff. destruct Z_le_dec; try destruct Z_lt_dec; intuition (try discriminate).
      rewrite Z2Nat.id; lia.
  }
  rewrite <- H3. rewrite seqZ_length. rewrite Z2Nat.id; lia.
+ intros. destruct a. 
  destruct x. reflexivity.
  specialize (H2 z). contradict H2. destruct Z_le_dec. 
  destruct Z_lt_dec. lia. intuition. intuition.
Qed.