Parcoursup / Calcul de l'ordre d'appel des candidats index
module Inversions use int.Int use int.NumOf use int.Sum use seq.Seq use proofs.lib.pair.Pair use proofs.lib.sum2d.Sum2d use proofs.lib.sum2d.Permutation type t predicate lt t t clone relations.PartialStrictOrder with type t = t, predicate rel = lt, axiom . predicate inversion (s: seq t) (p : pair) = (0 <= p.i < p.j < length s) && (lt s[p.j] s[p.i]) function inversions_count (s: seq t) (p : pair) : int = if inversion s p then 1 else 0 function nb_inversions (s: seq t) : int = sum2d (inversions_count s) (length s) (length s) let lemma nb_inversions_empty_or_singleton (s : seq t) requires { 0 <= length s <= 1 } ensures { nb_inversions s = 0 } = () let function swap (s:seq t) (p : pair) : seq t requires { 0 <= p.i < p.j < length s } ensures { length result = length s } ensures { result[p.i] = s[p.j] } ensures { result[p.j] = s[p.i] } ensures { forall k. (0 <= k < length s /\ k <> p.i /\ k <> p.j) -> result[k] = s[k] } = Seq.create (length s) (fun k -> s[if k = p.i then p.j else if k = p.j then p.i else k]) let function phi (p0 p: pair) : pair requires { in_quadrant p0 } = if p.i < p0.i && p.j = p0.i then mkp p.i p0.j else if p.i < p0.i && p.j = p0.j then mkp p.i p0.i else if p.i = p0.i && p0.j < p.j then mkp p0.j p.j else if p.i = p0.j && p0.j < p.j then mkp p0.i p.j else p let lemma phi_is_involution (p0 : pair) (n : int) requires { in_quadrant_n p0 n } ensures { is_involution (phi p0) n n } = () let lemma inversions_inc (s : seq t) (p0 : pair) requires { in_quadrant p0 } requires { inversion s p0 } ensures { forall p. inversion (swap s p0) p -> inversion s (phi p0 p) } = () use proofs.lib.sum2d.SemiLinearity let lemma inversions_less (s : seq t)(p0 : pair) requires { in_quadrant p0 } requires { inversion s p0 } ensures { let n = length s in let f = (inversions_count (swap s p0) ) in let g = ((inversions_count s) @ (phi p0)) in forall p. in_rect p n n -> f p <= g p } = inversions_inc s p0 let lemma inversions_dec (s : seq t) (p0 : pair) requires { in_quadrant p0 } requires { inversion s p0 } ensures { nb_inversions (swap s p0) < nb_inversions s } = let n = length s in assert { nb_inversions s = sum2d (inversions_count s) n n }; sum_permut (inversions_count s) (phi p0) n n; assert { sum2d (inversions_count s) n n = sum2d ( (inversions_count s) @ (phi p0) ) n n }; assert { (inversions_count (swap s p0) ) p0 < ((inversions_count s) @ (phi p0)) p0 }; let f = (inversions_count (swap s p0) ) in let g = ((inversions_count s) @ (phi p0)) in inversions_less s p0; sum2d_lt f g n n p0 end (* generated on Mon Dec 2 02:04:28 UTC 2024 from rev: *)
Generated by why3doc 1.7.2+git