let coercion f g d = 
  let def = Tapp (f , [Tapp(g,[d])]) in 
  match f,g,d with 
    | "data_of_addr""addr_of_data",_
    | "data_of_uint8""uint8_of_data",_ 
    | "data_of_sint8""sint8_of_data",_ 
    | "data_of_uint16""uint16_of_data",_
    | "data_of_sint16""sint16_of_data",_
    | "data_of_uint32""uint32_of_data",_
    | "data_of_sint32""sint32_of_data",_
    | "data_of_uint64""uint64_of_data",_
    | "data_of_sint64""sint64_of_data",_
    | "data_of_float16""float16_of_data",_
    | "data_of_float32""float32_of_data",_
    | "data_of_float64""float64_of_data",_
    | "data_of_float128""float128_of_data",_ -> d
    | "uint8_of_data""data_of_uint8",Tconst(ConstInt z)  ->
        let b = Big_int.big_int_of_int 256 in unsigned_in_bound b z d def
    | "sint8_of_data""data_of_sint8",Tconst(ConstInt z)  ->
        let b = Big_int.big_int_of_int 128 in signed_in_bound b z d def
    | "uint16_of_data""data_of_uint16",Tconst(ConstInt z)  ->
        let b = Big_int.big_int_of_int 65536 in unsigned_in_bound b z d def
    | "sint16_of_data""data_of_sint16",Tconst(ConstInt z)  ->
        let b = Big_int.big_int_of_int 32768 in signed_in_bound b z d def
    | "uint32_of_data""data_of_uint32",Tconst(ConstInt z)  ->
        let b = Big_int.big_int_of_string ("4294967296"in unsigned_in_bound b z d def
    | "sint32_of_data""data_of_sint32",Tconst(ConstInt z)  ->
        let b = Big_int.big_int_of_string ("2147483648"in signed_in_bound b z d def
    | "uint64_of_data""data_of_uint64",Tconst(ConstInt z)  ->
        let b = Big_int.big_int_of_string ("18446744073709551616"in unsigned_in_bound b z d def
    | "sint64_of_data""data_of_sint64",Tconst(ConstInt z)  ->
        let b = Big_int.big_int_of_string ("9223372036854775808"in signed_in_bound b z d def
    | _ -> def