let string_of_poly =
  let rec
    f = function
      deg, a, d -> let
                     str_sign = if gt_rat (cons_rat ("0""1"), a) then "-" else "+"
                     and
                     str = string_of_rat (if gt_rat (a, cons_rat ("0""1")) 
                                              then a 
                                              else opp_rat (a))
                   in
                     let
                       str_1 = if d = deg
                                then "" 
                                else " "
                       and
                       str_2 = if str_sign = "+" & d = deg 
                                then "" 
                                else str_sign ^ " "
                       and
                       str_3 = if d = 0 
                                then str 
                                else
                                  if eq_rat ((if gt_rat (a, cons_rat ("0""1")) 
                                                  then a 
                                                  else opp_rat (a)), 
                                               cons_rat ("1""1"))
                                    then ""
                                    else str ^ " " 
                       and
                       str_4 = if d = 0 
                                then ""
                                else
                                  if d = 1
                                    then "X"
                                    else "X" ^ string_of_int (d)
                     in
                       str_1 ^ str_2 ^ str_3 ^ str_4
  in
    function
      p -> let
             l_str = if is_null_poly (p)
                     then cons_list (string_of_rat (cons_rat ("0""1")), empty_list ())
                     else
                        let
                          l_coef_deg = coef_deg_list_of_poly (p)
                        in
                          (* l_coef_deg is not empty *)
                          let
                            deg = let (a, d) = head (l_coef_deg) in d
                          in
                            List.map (function a, d -> f (deg, a, d)) l_coef_deg
           in
             List.fold_right (function str_1 -> function str_2 -> str_1 ^ str_2) l_str ""