End Fsfun.
Canonical fsfun_of_funE K V default S h key x :=
Unlockable (@Fsfun.of_ffunE K V default S h key x).
Fact fsfun_key : unit. Proof. exact: tt. Qed.
Definition fsfun_of_ffun key (K : choiceType) (V : eqType)
(S : {fset K}) (h : S -> V) (default : K -> V) :=
(Fsfun.of_ffun default h key).
Definition fsfun_choiceMixin (K V : choiceType) (d : K -> V) :=
[choiceMixin of fsfun d by <:].
Canonical  fsfun_choiceType (K V : choiceType) (d : K -> V) :=
ChoiceType (fsfun d) (fsfun_choiceMixin d).
Delimit Scope fsfun_scope with fsfun.
Notation "[ 'fsfun[' key ] x : aT => F | default ]" :=
(fsfun_of_ffun key (fun x : aT => F) (fun x => default))
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun' x : aT => F | default ]" :=
[fsfun[fsfun_key] x : aT => F | default]
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun[' key ] x : aT => F ]" := [fsfun[key] x : aT => F | _]
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun' x : aT => F ]" := [fsfun x : aT => F | _]
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun[' key ] x => F | default ]" :=
[fsfun[key] x : _ => F | default ]
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun' x => F | default ]" := [fsfun x : _ => F | default]
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun[' key ] x => F ]" := [fsfun[key] x => F | _]
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun' x => F ]" := [fsfun x => F | _]
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun[' key ]=> F | default ]" :=
[fsfun[key] _ => F | default ]
(at level 0, only parsing) : fun_scope.
Notation "[ 'fsfun=>' F | default ]" := [fsfun _ => F | default]
(at level 0, only parsing) : fun_scope.
Notation "[ 'fsfun[' key ]=> F ]" := [fsfun[key]=> F | _]
(at level 0, only parsing) : fun_scope.
Notation "[ 'fsfun=>' F ]" := [fsfun=> F | _]
(at level 0, only parsing) : fun_scope.
Definition fsfun_of_fun key (K : choiceType) (V : eqType)
(S : {fset K}) (h : K -> V) default :=
[fsfun[key] x : S => h (val x) | default x].
Notation "[ 'fsfun[' key ] x 'in' S => F | default ]" :=
(fsfun_of_fun key S (fun x => F) (fun x => default))
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun' x 'in' S => F | default ]" :=
[fsfun[fsfun_key] x in S => F | default]
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun[' key ] x 'in' S => F ]" :=
[fsfun[key] x in S => F | _]
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun' x 'in' S => F ]" :=
[fsfun[fsfun_key] x in S => F | _]
(at level 0, x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun[' key ] 'in' S => F | default ]" :=
[fsfun[key] _ in S => F | default]
(at level 0, only parsing) : fun_scope.
Notation "[ 'fsfun' 'in' S => F | default ]" :=
[fsfun[fsfun_key] in S => F | default]
(at level 0, only parsing) : fun_scope.
Notation "[ 'fsfun[' key ] 'in' S => F ]" :=
[fsfun[key] in S => F | _]
(at level 0, only parsing) : fun_scope.
Notation "[ 'fsfun' 'in' S => F ]" :=
[fsfun[fsfun_key] in S => F | _]
(at level 0, only parsing) : fun_scope.
(* only printing *)
Notation "[ 'fs' 'fun' x : aT => F ]" := [fsfun[_] x : aT => F]
(at level 0, x at level 99,
format "[ 'fs' 'fun'  x  :  aT  =>  F ]") : fun_scope.
Notation "[ 'fs' 'fun' x 'in' aT => F ]" := [fsfun[_] x in aT => F]
(at level 0, x at level 99,
format "[ 'fs' 'fun'  x  'in'  aT  =>  F ]") : fun_scope.
Fact fsfun0_key : unit. Proof. exact: tt. Qed.
Notation "[ 'fsfun' 'for' default ]" := (fsfun_of_ffun fsfun0_key [fmap] default)
(at level 0, only parsing) : fun_scope.
Notation "[ 'fsfun' 'of' x => default ]" := [fsfun for fun x => default]
(at level 0,  x at level 99, only parsing) : fun_scope.
Notation "[ 'fsfun' 'with' default ]" := [fsfun of _ => default]
(at level 0, only parsing) : fun_scope.
Notation "[ 'fsfun' ]" := [fsfun for _]
(at level 0, format "[ 'fsfun' ]") : fun_scope.
Section FsfunTheory.
Variables (key : unit) (K : choiceType) (V : eqType) (default : K -> V).

(* Specifications: *)
Lemma fsfun_ffun (S : {fset K}) (h : S -> V) (x : K) :
[fsfun[key] a : S => h a | default a] x =
odflt (default x) (omap h (insub x)).
Lemma finsupp0 : finsupp [fsfun for default] = fset0.
Lemma fscomp0f : left_id [fsfun] fsfun_comp.
Lemma fsinjectiveP f : reflect (injective f) (fsinjectiveb f).
Lemma fsinjectivebP f :
reflect (exists2 S : {fset K}, (finsupp f `<=` S)
& {in S &, injective f} /\ forall a : S, f (val a) \in S)
(fsinjectiveb f).