(module main)

(import math (abs_i32 neg_i32 rem_i32 bit_and_i32 bit_or_i32 bit_xor_i32 is_even_i32 is_odd_i32 min_i32 max_i32 clamp_i32 square_i32 cube_i32 is_zero_i32 is_positive_i32 is_negative_i32 in_range_i32 abs_i64 neg_i64 rem_i64 bit_and_i64 bit_or_i64 bit_xor_i64 is_even_i64 is_odd_i64 min_i64 max_i64 clamp_i64 square_i64 cube_i64 is_zero_i64 is_positive_i64 is_negative_i64 in_range_i64 abs_f64 neg_f64 min_f64 max_f64 clamp_f64 square_f64 cube_f64 is_zero_f64 is_positive_f64 is_negative_f64 in_range_f64))

(fn imported_i32_score () -> i32
  (clamp_i32 (+ (square_i32 (abs_i32 (neg_i32 6))) (max_i32 (min_i32 (cube_i32 1) 7) 6)) 0 42))

(fn imported_i64_score () -> i64
  (clamp_i64 (+ (square_i64 (abs_i64 (neg_i64 6i64))) (max_i64 (min_i64 (cube_i64 1i64) 7i64) 6i64)) 0i64 42i64))

(fn imported_f64_score () -> f64
  (clamp_f64 (+ (square_f64 (abs_f64 (neg_f64 6.0))) (max_f64 (min_f64 (cube_f64 1.0) 7.0) 6.0)) 0.0 42.0))

(fn imported_i32_predicates_ok () -> bool
  (if (is_zero_i32 (neg_i32 0))
    (if (is_positive_i32 (abs_i32 -5))
      (if (is_negative_i32 (neg_i32 5))
        (if (= (rem_i32 17 5) 2)
          (if (is_even_i32 42)
            (if (is_odd_i32 -41)
              (if (= (bit_and_i32 6 3) 2)
                (if (= (bit_or_i32 4 2) 6)
                  (if (= (bit_xor_i32 7 3) 4)
                    (in_range_i32 (imported_i32_score) 0 42)
                    false)
                  false)
                false)
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_i64_predicates_ok () -> bool
  (if (is_zero_i64 (neg_i64 0i64))
    (if (is_positive_i64 (abs_i64 -5i64))
      (if (is_negative_i64 (neg_i64 5i64))
        (if (= (rem_i64 17i64 5i64) 2i64)
          (if (is_even_i64 42i64)
            (if (is_odd_i64 -41i64)
              (if (= (bit_and_i64 6i64 3i64) 2i64)
                (if (= (bit_or_i64 4i64 2i64) 6i64)
                  (if (= (bit_xor_i64 7i64 3i64) 4i64)
                    (in_range_i64 (imported_i64_score) 0i64 42i64)
                    false)
                  false)
                false)
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_f64_predicates_ok () -> bool
  (if (is_zero_f64 (neg_f64 0.0))
    (if (is_positive_f64 (abs_f64 -5.0))
      (if (is_negative_f64 (neg_f64 5.0))
        (in_range_f64 (imported_f64_score) 0.0 42.0)
        false)
      false)
    false))

(fn imported_i32_helpers_ok () -> bool
  (if (= (imported_i32_score) 42)
    (imported_i32_predicates_ok)
    false))

(fn imported_i64_helpers_ok () -> bool
  (if (= (imported_i64_score) 42i64)
    (imported_i64_predicates_ok)
    false))

(fn imported_f64_helpers_ok () -> bool
  (if (= (imported_f64_score) 42.0)
    (imported_f64_predicates_ok)
    false))

(fn imported_math_helpers_ok () -> bool
  (if (imported_i32_helpers_ok)
    (if (imported_i64_helpers_ok)
      (imported_f64_helpers_ok)
      false)
    false))

(fn main () -> i32
  (if (imported_math_helpers_ok)
    42
    1))

(test "explicit local math import i32 helpers"
  (imported_i32_helpers_ok))

(test "explicit local math import i64 helpers"
  (imported_i64_helpers_ok))

(test "explicit local math import f64 helpers"
  (imported_f64_helpers_ok))

(test "explicit local math import all helpers"
  (= (main) 42))
