let rec if_value_to_string (atom_to_string : (Types.if_value_type -> string)) (if_value : Types.if_value_type) : string =
  let if_value_to_string_aux = if_value_to_string atom_to_string in
  match if_value with
    If_address _ | If_const _ ->
      atom_to_string if_value
  | If_pair(term1,term2) ->
      "pair("^(if_value_to_string_aux term1)^","
      ^(if_value_to_string_aux term2)^")"
  | If_scrypt(term1,term2) ->
      "scrypt("^(if_value_to_string_aux term2)^","
      ^(if_value_to_string_aux term1)^")"
  | If_crypt(term1,term2) ->
      "crypt("^(if_value_to_string_aux term2)^","
      ^(if_value_to_string_aux term1)^")"
  | If_inv(term) ->
      "inv("^(if_value_to_string_aux term)^")"
  | If_function(term1,termlist) ->
      begin
        match term1 with
            If_const(fun_id) ->
              let fun_string = (string_id#get_name fun_id) in
                if (fun_string = "exp"|| (fun_string = "xor"then
                  fun_string^"("
                  ^(list_to_string if_value_to_string_aux "," termlist)
                  ^")"
                else
                  "apply("
                  ^(if_value_to_string_aux term1)
                  ^","
                  ^(list2_to_string if_value_to_string_aux "," termlist)
                  ^")"
          | _ -> 
              "apply("^(if_value_to_string_aux term1)^","
              ^(list2_to_string if_value_to_string_aux "," termlist)^")"
      end
  | If_cons(term1,term2) ->
      "cons("^(if_value_to_string_aux term1)^","
      ^(if_value_to_string_aux term2)^")"
  | If_delete(term1,term2) ->
      "delete("^(if_value_to_string_aux term1)^","
      ^(if_value_to_string_aux term2)^")"
  | If_set(termlist) ->
      "set("^(list_to_string if_value_to_string_aux "," termlist)^")"