f a is ill-typed where f:forall 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 0 else 1.
bool_in_nat is defined
Coq < Coercion bool_in_nat : bool >-> nat.
bool_in_nat is now a coercion
Coq < Check (0 = true).
0 = true
: Prop
Coq < Set Printing Coercions.
Coq < Check (0 = true).
0 = 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 none.
We give an example of coercion between classes with parameters.
Coq < Parameters
Coq < (C : nat -> Set) (D : nat -> bool -> Set) (E : bool -> Set).
C is assumed
D is assumed
E is assumed
Coq < Parameter f : forall n:nat, C n -> D (S n) true.
f is assumed
Coq < Coercion f : C >-> D.
f is now a coercion
Coq < Parameter g : forall (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 0.
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 1 true (f 0 c))
: nat
We give now an example using identity coercions.
Coq < Definition D' (b:bool) := D 1 b.
D' is defined
Coq < Identity Coercion IdD'D : D' >-> D.
Coq < Print IdD'D.
IdD'D =
(fun (b : bool) (x : D' b) => x):forall b : bool, D' b -> D 1 b
: forall b : bool, D' b -> D 1 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 1 true d')
: nat
In the case of functional arguments, we use the monotonic rule of
sub-typing. Approximatively, to coerce t:forall x:A, B towards
forall 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 0.
t is assumed
Coq < Check (U t).
U (fun x : A => t x)
: nat
Coq < Set Printing Coercions.
Coq < Check (U t).
U (fun x : A => g 1 true (f 0 (t (h x))))
: nat
Remark the changes in the result following the modification of the
previous example.
Coq < Parameter U' : (C 0 -> B) -> nat.
U' is assumed
Coq < Parameter t' : E true -> A.
t' is assumed
Coq < Check (U' t').
U' (fun x : C 0 => t' x)
: nat
Coq < Set Printing Coercions.
Coq < Check (U' t').
U' (fun x : C 0 => h (t' (g 1 true (f 0 x))))
: nat