let type_conversions () =
  let typconv_axiom ty1 ty1_to_ty2 ty2_to_ty1 =
    let x = PExpr.mkvar ~name:"x" () in
    let app1 = PExpr.mkapp ~fun_name:ty1_to_ty2 ~args:[x] () in
    let app2 = PExpr.mkapp ~fun_name:ty2_to_ty1 ~args:[app1] () in
    let eq = PExpr.mkeq ~expr1:x ~expr2:app2 () in
    let forall =
      PExpr.mkforall ~typ:(ctype ty1)
        ~vars:[new identifier "x"] ~body:eq ()
    in
    PDecl.mklemma_def ~name:(unique_logic_name (ty1_to_ty2 ^ "_axiom")) ~axiom:true
      ~body:forall ()
  in
  Hashtbl.fold
    (fun _ (ty1,ty2,ty1_to_ty2,ty2_to_ty1) acc ->
       [
         PDecl.mklogic_def ~typ:(ctype ty2) ~name:ty1_to_ty2
           ~params:[ctype ty1, "x"] ~reads:[] ();
         PDecl.mklogic_def ~typ:(ctype ty1) ~name:ty2_to_ty1
           ~params:[ctype ty2, "x"] ~reads:[] ();
         typconv_axiom ty1 ty1_to_ty2 ty2_to_ty1;
         typconv_axiom ty2 ty2_to_ty1 ty1_to_ty2
       ] @ acc
    ) type_conversion_table []