(module main)

(import std.vec_i32 (empty append len at singleton append2 append3 pair triple repeat range range_from_zero is_empty index_or first_or last_or index_option first_option last_option index_of_option last_index_of_option count_of contains sum concat take starts_with without_prefix ends_with without_suffix drop reverse subvec insert_at insert_range replace_at replace_range remove_at remove_range))

(fn imported_empty_length () -> i32
  (len (empty)))

(fn imported_pair_index () -> i32
  (at (pair 40 41) 1))

(fn imported_builder_helpers_ok () -> bool
  (if (= (len (singleton 42)) 1)
    (if (= (len (append2 (empty) 10 20)) 2)
      (if (= (len (append3 (singleton 10) 20 30 40)) 4)
        (= (pair 5 6) (append2 (empty) 5 6))
        false)
      false)
    false))

(fn imported_constructor_helpers_ok () -> bool
  (if (= (repeat 7 -4) (empty))
    (if (= (repeat 7 0) (empty))
      (if (= (repeat 7 3) (triple 7 7 7))
        (if (= (range_from_zero -1) (empty))
          (if (= (range_from_zero 0) (empty))
            (if (= (range_from_zero 4) (append (triple 0 1 2) 3))
              (= (range_from_zero 2) (pair 0 1))
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_range_helpers_ok () -> bool
  (if (= (range -3 2) (append3 (pair -3 -2) -1 0 1))
    (if (= (range 3 7) (append2 (pair 3 4) 5 6))
      (if (= (range -2 -2) (empty))
        (= (range 7 3) (empty))
        false)
      false)
    false))

(fn option_is_some_value ((value (option i32)) (expected i32)) -> bool
  (if (is_some value)
    (= (unwrap_some value) expected)
    false))

(fn imported_option_query_helpers_ok () -> bool
  (if (is_none (first_option (empty)))
    (if (option_is_some_value (first_option (pair 40 41)) 40)
      (if (is_none (last_option (empty)))
        (if (option_is_some_value (last_option (triple 10 20 30)) 30)
          (if (is_none (index_option (pair 40 41) -1))
            (if (is_none (index_option (pair 40 41) 9))
              (option_is_some_value (index_option (pair 40 41) 1) 41)
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_query_helpers_ok () -> bool
  (if (is_empty (empty))
    (if (= (first_or (empty) 9) 9)
      (if (= (first_or (pair 40 41) 9) 40)
        (if (= (last_or (triple 10 20 30) 9) 30)
          (if (= (index_or (pair 40 41) -1 7) 7)
            (if (= (index_or (pair 40 41) 9 7) 7)
              (if (= (index_or (pair 40 41) 1 7) 41)
                (if (is_none (first_option (empty)))
                  (if (option_is_some_value (first_option (pair 40 41)) 40)
                    (if (option_is_some_value (last_option (triple 10 20 30)) 30)
                      (if (is_none (index_option (pair 40 41) -1))
                        (if (is_none (index_option (pair 40 41) 9))
                          (option_is_some_value (index_option (pair 40 41) 1) 41)
                          false)
                        false)
                      false)
                    false)
                  false)
                false)
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_starts_with_helper_ok () -> bool
  (let values (vec i32) (append2 (triple 10 20 30) 40 50))
  (let prefix (vec i32) (pair 10 20))
  (let longer_prefix (vec i32) (append2 values 60 70))
  (let mismatched_prefix (vec i32) (pair 20 30))
  (if (starts_with values (empty))
    (if (starts_with values prefix)
      (if (starts_with values values)
        (if (starts_with values longer_prefix)
          false
          (if (starts_with values mismatched_prefix)
            false
            (if (= values (append2 (triple 10 20 30) 40 50))
              (= prefix (pair 10 20))
              false)))
        false)
      false)
    false))

(fn imported_ends_with_helper_ok () -> bool
  (let values (vec i32) (append2 (triple 10 20 30) 40 50))
  (let suffix (vec i32) (pair 40 50))
  (let longer_suffix (vec i32) (append2 values 60 70))
  (let mismatched_suffix (vec i32) (pair 40 51))
  (if (ends_with values (empty))
    (if (ends_with values suffix)
      (if (ends_with values values)
        (if (ends_with values longer_suffix)
          false
          (if (ends_with values mismatched_suffix)
            false
            (if (= values (append2 (triple 10 20 30) 40 50))
              (= suffix (pair 40 50))
              false)))
        false)
      false)
    false))

(fn imported_without_suffix_helper_ok () -> bool
  (let values (vec i32) (append2 (triple 10 20 30) 40 50))
  (let suffix (vec i32) (pair 40 50))
  (let longer_suffix (vec i32) (append2 values 60 70))
  (let mismatched_suffix (vec i32) (pair 40 51))
  (if (= (without_suffix values (empty)) values)
    (if (= (without_suffix values values) (empty))
      (if (= (without_suffix values suffix) (triple 10 20 30))
        (if (= (without_suffix values longer_suffix) values)
          (if (= (without_suffix values mismatched_suffix) values)
            (if (= values (append2 (triple 10 20 30) 40 50))
              (= suffix (pair 40 50))
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_without_prefix_helper_ok () -> bool
  (let values (vec i32) (append2 (triple 10 20 30) 40 50))
  (let prefix (vec i32) (pair 10 20))
  (let longer_prefix (vec i32) (append2 values 60 70))
  (let mismatched_prefix (vec i32) (pair 10 21))
  (if (= (without_prefix values (empty)) values)
    (if (= (without_prefix values values) (empty))
      (if (= (without_prefix values prefix) (triple 30 40 50))
        (if (= (without_prefix values longer_prefix) values)
          (if (= (without_prefix values mismatched_prefix) values)
            (if (= values (append2 (triple 10 20 30) 40 50))
              (= prefix (pair 10 20))
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_transform_helpers_ok () -> bool
  (if (= (concat (empty) (pair 7 8)) (pair 7 8))
    (if (= (concat (pair 1 2) (triple 3 4 5)) (append3 (pair 1 2) 3 4 5))
      (if (= (take (triple 10 20 30) -4) (empty))
        (if (= (take (triple 10 20 30) 2) (pair 10 20))
          (if (= (take (pair 10 20) 9) (pair 10 20))
            (if (= (drop (triple 10 20 30) -4) (triple 10 20 30))
              (if (= (drop (triple 10 20 30) 2) (singleton 30))
                (if (= (drop (pair 10 20) 9) (empty))
                  (if (= (reverse (empty)) (empty))
                    (= (reverse (append3 (pair 10 20) 30 40 50)) (append3 (pair 50 40) 30 20 10))
                    false)
                  false)
                false)
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_subvec_helper_ok () -> bool
  (let values (vec i32) (append (triple 10 20 30) 40))
  (if (= (subvec values 1 3) (pair 20 30))
    (if (= (subvec values 2 9) (pair 30 40))
      (if (= (subvec values 2 2) (empty))
        (if (= (subvec values 4 9) (empty))
          (if (= (subvec values -1 2) (empty))
            (= values (append (triple 10 20 30) 40))
            false)
          false)
        false)
      false)
    false))

(fn imported_insert_helper_ok () -> bool
  (let values (vec i32) (triple 10 20 30))
  (if (= (insert_at values 1 99) (append2 (pair 10 99) 20 30))
    (if (= (insert_at values 3 99) (append values 99))
      (if (= values (triple 10 20 30))
        (if (= (insert_at values -1 99) values)
          (= (insert_at values 4 99) values)
          false)
        false)
      false)
    false))

(fn imported_insert_range_helper_ok () -> bool
  (let values (vec i32) (triple 10 20 30))
  (let inserted (vec i32) (pair 70 80))
  (if (= (insert_range values 1 inserted) (append3 (pair 10 70) 80 20 30))
    (if (= (len (insert_range values 1 inserted)) (+ (len values) (len inserted)))
      (if (= (insert_range values 3 inserted) (append2 values 70 80))
        (if (= values (triple 10 20 30))
          (if (= inserted (pair 70 80))
            (if (= (insert_range values -1 inserted) values)
              (= (insert_range values 4 inserted) values)
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_replace_helper_ok () -> bool
  (if (= (replace_at (triple 10 20 30) 1 99) (triple 10 99 30))
    (if (= (replace_at (triple 10 20 30) -1 99) (triple 10 20 30))
      (= (replace_at (pair 10 20) 2 99) (pair 10 20))
      false)
    false))

(fn imported_replace_range_helper_ok () -> bool
  (let values (vec i32) (append2 (triple 10 20 30) 40 50))
  (let replacement (vec i32) (pair 77 88))
  (if (= (replace_range values 1 3 replacement) (append3 (pair 10 77) 88 40 50))
    (if (= (replace_range values 3 99 replacement) (append2 (triple 10 20 30) 77 88))
      (if (= (replace_range values 2 2 replacement) values)
        (if (= (replace_range values 5 7 replacement) values)
          (if (= (replace_range values -1 2 replacement) values)
            (if (= values (append2 (triple 10 20 30) 40 50))
              (= replacement (pair 77 88))
              false)
            false)
          false)
        false)
      false)
    false))

(fn imported_remove_helper_ok () -> bool
  (if (= (remove_at (triple 10 20 30) 1) (pair 10 30))
    (if (= (remove_at (triple 10 20 30) -1) (triple 10 20 30))
      (= (remove_at (pair 10 20) 2) (pair 10 20))
      false)
    false))

(fn imported_remove_range_helper_ok () -> bool
  (let values (vec i32) (append2 (triple 10 20 30) 40 50))
  (if (= (remove_range values 1 3) (append2 (singleton 10) 40 50))
    (if (= (remove_range values 3 5) (triple 10 20 30))
      (if (= (remove_range values 2 2) values)
        (if (= (remove_range values 5 7) values)
          (if (= (remove_range values -1 2) values)
            (= values (append2 (triple 10 20 30) 40 50))
            false)
          false)
        false)
      false)
    false))

(fn imported_count_of_helper_ok () -> bool
  (let values (vec i32) (append3 (pair 10 20) 10 30 10))
  (if (= (count_of (empty) 10) 0)
    (if (= (count_of values 10) 3)
      (if (= (count_of values 20) 1)
        (if (= (count_of values 99) 0)
          (= values (append3 (pair 10 20) 10 30 10))
          false)
        false)
      false)
    false))

(fn imported_real_program_helpers_ok () -> bool
  (if (contains (triple 10 20 30) 20)
    (if (contains (triple 10 20 30) 99)
      false
      (if (option_is_some_value (index_of_option (append3 (pair 10 20) 30 20 10) 20) 1)
        (if (option_is_some_value (last_index_of_option (append3 (pair 10 20) 30 20 10) 20) 3)
          (if (is_none (index_of_option (append3 (pair 10 20) 30 20 10) 99))
            (if (is_none (last_index_of_option (append3 (pair 10 20) 30 20 10) 99))
              (= (sum (append3 (empty) 10 20 12)) 42)
              false)
            false)
          false)
        false))
    false))

(fn imported_vec_i32_helpers_ok () -> bool
  (if (= (imported_empty_length) 0)
    (if (= (imported_pair_index) 41)
      (if (imported_builder_helpers_ok)
        (if (imported_constructor_helpers_ok)
          (if (imported_range_helpers_ok)
            (if (imported_query_helpers_ok)
              (if (imported_option_query_helpers_ok)
                (if (imported_starts_with_helper_ok)
                  (if (imported_ends_with_helper_ok)
                    (if (imported_without_suffix_helper_ok)
                      (if (imported_without_prefix_helper_ok)
                        (if (imported_transform_helpers_ok)
                          (if (imported_subvec_helper_ok)
                            (if (imported_insert_helper_ok)
                              (if (imported_insert_range_helper_ok)
                                (if (imported_replace_helper_ok)
                                  (if (imported_replace_range_helper_ok)
                                    (if (imported_remove_helper_ok)
                                      (if (imported_remove_range_helper_ok)
                                        (if (imported_count_of_helper_ok)
                                          (imported_real_program_helpers_ok)
                                          false)
                                        false)
                                      false)
                                    false)
                                  false)
                                false)
                              false)
                            false)
                          false)
                        false)
                      false)
                    false)
                  false)
                false)
              false)
            false)
          false)
        false)
      false)
    false))

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

(test "explicit std vec_i32 empty len facade"
  (= (imported_empty_length) 0))

(test "explicit std vec_i32 direct at facade"
  (= (imported_pair_index) 41))

(test "explicit std vec_i32 builder helpers"
  (imported_builder_helpers_ok))

(test "explicit std vec_i32 constructor helpers"
  (imported_constructor_helpers_ok))

(test "explicit std vec_i32 range helper"
  (imported_range_helpers_ok))

(test "explicit std vec_i32 query helpers"
  (imported_query_helpers_ok))

(test "explicit std vec_i32 option query helpers"
  (imported_option_query_helpers_ok))

(test "explicit std vec_i32 starts_with helper"
  (imported_starts_with_helper_ok))

(test "explicit std vec_i32 ends_with helper"
  (imported_ends_with_helper_ok))

(test "explicit std vec_i32 without_suffix helper"
  (imported_without_suffix_helper_ok))

(test "explicit std vec_i32 without_prefix helper"
  (imported_without_prefix_helper_ok))

(test "explicit std vec_i32 transform helpers"
  (imported_transform_helpers_ok))

(test "explicit std vec_i32 subvec helper"
  (imported_subvec_helper_ok))

(test "explicit std vec_i32 insert helper"
  (imported_insert_helper_ok))

(test "explicit std vec_i32 insert range helper"
  (imported_insert_range_helper_ok))

(test "explicit std vec_i32 replace helper"
  (imported_replace_helper_ok))

(test "explicit std vec_i32 replace range helper"
  (imported_replace_range_helper_ok))

(test "explicit std vec_i32 remove helper"
  (imported_remove_helper_ok))

(test "explicit std vec_i32 remove range helper"
  (imported_remove_range_helper_ok))

(test "explicit std vec_i32 count_of helper"
  (imported_count_of_helper_ok))

(test "explicit std vec_i32 real program helpers"
  (imported_real_program_helpers_ok))

(test "explicit std vec_i32 helpers all"
  (= (main) 42))
