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.
|