## 14.11 Examples

There are three situations:

- (f a) is ill-typed where f:(x:A)B and a:A'. If there is a coercion path between A' and A, (f a) is transformed into (f a') where a' is the result of the application of this coercion path to a.
  We first give an example of coercion between atomic inductive types
  `Coq` `<``Definition bool_in_nat := [b:bool]if b then O else (S O).`
  `bool_in_nat is defined`
  `Coq` `<``Coercion bool_in_nat : bool` `>``-``>``nat.`
  `bool_in_nat is now a coercion`
  `Coq` `<``Check O=true.`
  `O=true`
  `: Prop`
  `Coq` `<``Set Printing Coercions.`
  `Coq` `<``Check O=true.`
  `O=(bool_in_nat true)`
  `: Prop`
  Warning: ```Check true=O.`'' fails. This is ``normal'' behaviour of coercions. To validate `true=O`, the coercion is searched from `nat` to `bool`. There is no one.
  We give an example of coercion between classes with parameters.
  `Coq` `<``Parameters C:nat-``>``Set; D:nat-``>``bool-``>``Set; E:bool-``>``Set.`
  `C is assumed`
  `D is assumed`
  `E is assumed`
  `Coq` `<``Parameter f : (n:nat)(C n) -``>``(D (S n) true).`
  `f is assumed`
  `Coq` `<``Coercion f : C` `>``-``>``D.`
  `f is now a coercion`
  `Coq` `<``Parameter g : (n:nat)(b:bool)(D n b) -``>``(E b).`
  `g is assumed`
  `Coq` `<``Coercion g : D` `>``-``>``E.`
  `g is now a coercion`
  `Coq` `<``Parameter c : (C O).`
  `c is assumed`
  `Coq` `<``Parameter T : (E true) -``>``nat.`
  `T is assumed`
  `Coq` `<``Check (T c).`
  `(T c)`
  `: nat`
  `Coq` `<``Set Printing Coercions.`
  `Coq` `<``Check (T c).`
  `(T (g (S O) true (f O c)))`
  `: nat`
  We give now an example using identity coercions.
  `Coq` `<``Definition D' := [b:bool](D (S O) b).`
  `D' is defined`
  `Coq` `<``Identity Coercion IdD'D : D'` `>``-``>``D.`
  `Coq` `<``Print IdD'D.`
  `IdD'D =`
  `([b:bool; x:(D' b)]x)::((b:bool)(D' b)-``>``(D (S O) b))`
  `: (b:bool)(D' b)-``>``(D (S O) b)`
  `Coq` `<``Parameter d' : (D' true).`
  `d' is assumed`
  `Coq` `<``Check (T d').`
  `(T d')`
  `: nat`
  `Coq` `<``Set Printing Coercions.`
  `Coq` `<``Check (T d').`
  `(T (g (S O) true d'))`
  `: nat`
  In the case of functional arguments, we use the monotonic rule of sub-typing. Approximatively, to coerce t:(x:A)B towards (x:A')B', one have to coerce A' towards A and B towards B'. An example is given below:
  `Coq` `<``Parameters A,B:Set; h:A-``>``B.`
  `A is assumed`
  `B is assumed`
  `h is assumed`
  `Coq` `<``Coercion h : A` `>``-``>``B.`
  `h is now a coercion`
  `Coq` `<``Parameter U : (A -``>``(E true)) -``>``nat.`
  `U is assumed`
  `Coq` `<``Parameter t : B -``>``(C O).`
  `t is assumed`
  `Coq` `<``Check (U t).`
  `(U [x:A](t x))`
  `: nat`
  `Coq` `<``Set Printing Coercions.`
  `Coq` `<``Check (U t).`
  `(U [x:A](g (S O) true (f O (t (h x)))))`
  `: nat`
  Remark the changes in the result following the modification of the previous example.
  `Coq` `<``Parameter U' : ((C O) -``>``B) -``>``nat.`
  `U' is assumed`
  `Coq` `<``Parameter t' : (E true) -``>``A.`
  `t' is assumed`
  `Coq` `<``Check (U' t').`
  `(U' [x:(C O)](t' x))`
  `: nat`
  `Coq` `<``Set Printing Coercions.`
  `Coq` `<``Check (U' t').`
  `(U' [x:(C O)](h (t' (g (S O) true (f O x)))))`
  `: nat`
- An assumption x:A when A is not a type, is ill-typed. It is replaced by x:A' where A' is the result of the application to A of the coercion path between the class of A and `SORTCLASS` if it exists. This case occurs in the abstraction [x:A]t, universal quantification (x:A)B, global variables and parameters of (co-)inductive definitions and functions. In (x:A)B, such a coercion path may be applied to B also if necessary.
  `Coq` `<``Parameter Graph : Type.`
  `Graph is assumed`
  `Coq` `<``Parameter Node : Graph -``>``Type.`
  `Node is assumed`
  `Coq` `<``Coercion Node : Graph` `>``-``>``SORTCLASS.`
  `Node is now a coercion`
  `Coq` `<``Parameter G : Graph.`
  `G is assumed`
  `Coq` `<``Parameter Arrows : G -``>``G -``>``Type.`
  `Arrows is assumed`
  `Coq` `<``Check Arrows.`
  `Arrows`
  `: G-``>``G-``>``Type`
  `Coq` `<``Parameter fg : G -``>``G.`
  `fg is assumed`
  `Coq` `<``Check fg.`
  `fg`
  `: G-``>``G`
  `Coq` `<``Set Printing Coercions.`
  `Coq` `<``Check fg.`
  `fg`
  `: (Node G)-``>``(Node G)`
- (f a) is ill-typed because f:A is not a function. The term f is replaced by the term obtained by applying to f the coercion path between A and `FUNCLASS` if it exists.
  `Coq` `<``Parameter bij : Set -``>``Set -``>``Set.`
  `bij is assumed`
  `Coq` `<``Parameter ap : (A,B:Set)(bij A B) -``>``A -``>``B.`
  `ap is assumed`
  `Coq` `<``Coercion ap : bij` `>``-``>``FUNCLASS.`
  `ap is now a coercion`
  `Coq` `<``Parameter b : (bij nat nat).`
  `b is assumed`
  `Coq` `<``Check (b O).`
  `(b O)`
  `: nat`
  `Coq` `<``Set Printing Coercions.`
  `Coq` `<``Check (b O).`
  `(ap nat nat b O)`
  `: nat`
  Let us see the resulting graph of this session.
  `Coq` `<``Print Graph.`
  `[ap] : bij` `>``-``>``FUNCLASS`
  `[Node] : Graph` `>``-``>``SORTCLASS`
  `[h] : A` `>``-``>``B`
  `[IdD'D; g] : D'` `>``-``>``E`
  `[IdD'D] : D'` `>``-``>``D`
  `[f; g] : C` `>``-``>``E`
  `[g] : D` `>``-``>``E`
  `[f] : C` `>``-``>``D`
  `[bool_in_nat] : bool` `>``-``>``nat`