End Extrema.
Notation "[ 'arg' 'min_' ( i < i0 | P ) F ]" :=
(arg_min i0 (fun i => P%B) (fun i => F))
(at level 0, i, i0 at level 10,
format "[ 'arg'  'min_' ( i  <  i0  |  P )  F ]") : form_scope.
Notation "[ 'arg' 'min_' ( i < i0 'in' A ) F ]" :=
[arg min_(i < i0 | i \in A) F]
(at level 0, i, i0 at level 10,
format "[ 'arg'  'min_' ( i  <  i0  'in'  A )  F ]") : form_scope.
Notation "[ 'arg' 'min_' ( i < i0 ) F ]" := [arg min_(i < i0 | true) F]
(at level 0, i, i0 at level 10,
format "[ 'arg'  'min_' ( i  <  i0 )  F ]") : form_scope.
Notation "[ 'arg' 'max_' ( i > i0 | P ) F ]" :=
(arg_max i0 (fun i => P%B) (fun i => F))
(at level 0, i, i0 at level 10,
format "[ 'arg'  'max_' ( i  >  i0  |  P )  F ]") : form_scope.
Notation "[ 'arg' 'max_' ( i > i0 'in' A ) F ]" :=
[arg max_(i > i0 | i \in A) F]
(at level 0, i, i0 at level 10,
format "[ 'arg'  'max_' ( i  >  i0  'in'  A )  F ]") : form_scope.
Notation "[ 'arg' 'max_' ( i > i0 ) F ]" := [arg max_(i > i0 | true) F]
(at level 0, i, i0 at level 10,
format "[ 'arg'  'max_' ( i  >  i0 ) F ]") : form_scope.
(**********************************************************************)
(*                                                                    *)
(*  Boolean injectivity test for functions with a finType domain      *)
(*                                                                    *)
(**********************************************************************)
Section Injectiveb.
Variables (aT : finType) (rT : eqType) (f : aT -> rT).
Implicit Type D : pred aT.
Definition dinjectiveb D := uniq (map f (enum D)).
Definition injectiveb := dinjectiveb aT.

(* Specifications: *)
Lemma dinjectivePn D :
reflect (exists2 x, x \in D & exists2 y, y \in [predD1 D & x] & f x = f y)
(~~ dinjectiveb D).
Lemma dinjectiveP D : reflect {in D &, injective f} (dinjectiveb D).
Lemma injectivePn :
reflect (exists x, exists2 y, x != y & f x = f y) (~~ injectiveb).
Lemma injectiveP : reflect (injective f) injectiveb.
Lemma codomP y : reflect (exists x, y = f x) (y \in codom f).
Definition iinv A y fAy := s2val (@iinv_proof A y fAy).
Lemma f_iinv A y fAy : f (@iinv A y fAy) = y.
Lemma preim_iinv A B y fAy : preim f B (@iinv A y fAy) = B y.
Lemma bij_on_image A (x0 : T) : {on [pred y in image f A], bijective f}.
End Image.