let rec e_prim f ts =
    if not (simpl()) then Tprim(f,ts) else
      match f , ts with
        | I_opp , [ Tprim(I_opp,[a]) ] -> a
        | R_opp , [ Tprim(R_opp,[a]) ] -> a
        | I_add , [ Tint a ; Tint b ] -> i_compute My_bigint.add a b
        | I_sub , [ Tint a ; Tint b ] -> i_compute My_bigint.sub a b
        | I_mul , [ Tint a ; Tint b ] -> i_compute My_bigint.mul a b
        | I_add , [ Tint "0" ; x ] -> x
        | I_add , [ x ; Tint "0" ] -> x
        | I_sub , [ Tint "0" ; x ] -> e_prim I_opp [x]
        | I_sub , [ x ; Tint "0" ] -> x
        | I_opp , [ Tint a ] -> i_compute My_bigint.sub "0" a
        | I_mul , [ Tint "1" ; x ] -> x
        | I_mul , [ x ; Tint "1" ] -> x
        | I_mul , [ Tint "0" ; _ ] -> e_zero
        | I_mul , [ _ ; Tint "0" ] -> e_zero
        | I_add , [ b ; Tprim(I_sub,[a;c]) ] when equal b c -> a ;
        | I_add , [ Tprim(I_sub,[a;b]) ; c ] when equal b c -> a
        | I_sub , [ Tprim(I_add,[a;b]) ; c ] when equal b c -> a
        | L_eq ,  [ Tint a ; Tint b ] -> i_compare (fun r -> r=0)  a b
        | L_neq , [ Tint a ; Tint b ] -> i_compare (fun r -> r<>0) a b
        | I_lt ,  [ Tint a ; Tint b ] -> i_compare (fun r -> r<0)  a b
        | L_eq  , [a;b] when equal a b -> Ttrue
        | L_neq , [a;b] when equal a b -> Tfalse
        | I_leq ,  [ Tint a ; Tint b ] -> i_compare (fun r -> r<=0) a b
        | I_of_R , [ Tprim(R_of_I,[a]) ] -> a
        | B_not , [p] -> e_not p
        | B_and , [a;b] -> e_and a b
        | B_or  , [a;b] -> e_or a b
        | _ -> Tprim(f,ts)