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