Module FinfunDef : FinfunDefSig.
Definition finfun := finfun_def.
End FinfunDef.
Notation finfun := FinfunDef.finfun.
Canonical finfun_unlock := Unlockable FinfunDef.finfunE.
Arguments finfun {aT rT} g.
Notation "[ 'ffun' x : aT => E ]" := (finfun (fun x : aT => E))
(at level 0, x ident) : fun_scope.
Notation "[ 'ffun' x => E ]" := (@finfun _ (fun=> _) (fun x => E))
(at level 0, x ident, format "[ 'ffun'  x  =>  E ]") : fun_scope.
Notation "[ 'ffun' => E ]" := [ffun _ => E]
(at level 0, format "[ 'ffun' =>  E ]") : fun_scope.
(* Example outcommented. (* Examples of using finite functions as containers in recursive inductive    *)
(* types, and making use of the fact that the type and accessor are           *)
(* structurally positive and decreasing, respectively.                        *)
Unset Elimination Schemes.
Inductive tree := node n of tree ^ n.
Fixpoint size t := let: node n f := t in sumn (codom (size \o f)) + 1.
Example tree_step (K : tree -> Type) :=
forall n st (t := node st) & forall i : 'I_n, K (st i), K t.
Example tree_rect K (Kstep : tree_step K) : forall t, K t.

Lemma ffunK : @cancel (finPi aT rT) fT fun_of_fin finfun.