(* Generated by coq-of-rust *)
Require Import CoqOfRust.CoqOfRust.

Module str.
  (*
  const fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
      crate::intrinsics::const_eval_select((s, begin, end), slice_error_fail_ct, slice_error_fail_rt)
  }
  *)
  Definition slice_error_fail (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ s; begin; end_ ] =>
      ltac:(M.monadic
        (let s := M.alloc (| s |) in
        let begin := M.alloc (| begin |) in
        let end_ := M.alloc (| end_ |) in
        M.call_closure (|
          M.get_function (|
            "core::intrinsics::const_eval_select",
            [
              Ty.tuple
                [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ]; Ty.path "usize"; Ty.path "usize" ];
              Ty.function
                [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ]; Ty.path "usize"; Ty.path "usize" ]
                (Ty.path "never");
              Ty.function
                [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ]; Ty.path "usize"; Ty.path "usize" ]
                (Ty.path "never");
              Ty.path "never"
            ]
          |),
          [
            Value.Tuple [ M.read (| s |); M.read (| begin |); M.read (| end_ |) ];
            M.get_function (| "core::str::slice_error_fail_ct", [] |);
            M.get_function (| "core::str::slice_error_fail_rt", [] |)
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_slice_error_fail : M.IsFunction "core::str::slice_error_fail" slice_error_fail.
  
  (*
  const fn slice_error_fail_ct(_: &str, _: usize, _: usize) -> ! {
      panic!("failed to slice string");
  }
  *)
  Definition slice_error_fail_ct (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ β0; β1; β2 ] =>
      ltac:(M.monadic
        (let β0 := M.alloc (| β0 |) in
        let β1 := M.alloc (| β1 |) in
        let β2 := M.alloc (| β2 |) in
        M.match_operator (|
          β0,
          [
            fun γ =>
              ltac:(M.monadic
                (M.match_operator (|
                  β1,
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          β2,
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (M.call_closure (|
                                  M.get_function (| "core::panicking::panic_fmt", [] |),
                                  [
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "core::fmt::Arguments",
                                        "new_const",
                                        []
                                      |),
                                      [
                                        M.alloc (|
                                          Value.Array
                                            [ M.read (| Value.String "failed to slice string" |) ]
                                        |)
                                      ]
                                    |)
                                  ]
                                |)))
                          ]
                        |)))
                  ]
                |)))
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_slice_error_fail_ct :
    M.IsFunction "core::str::slice_error_fail_ct" slice_error_fail_ct.
  
  (*
  fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! {
      const MAX_DISPLAY_LENGTH: usize = 256;
      let trunc_len = s.floor_char_boundary(MAX_DISPLAY_LENGTH);
      let s_trunc = &s[..trunc_len];
      let ellipsis = if trunc_len < s.len() { "[...]" } else { "" };
  
      // 1. out of bounds
      if begin > s.len() || end > s.len() {
          let oob_index = if begin > s.len() { begin } else { end };
          panic!("byte index {oob_index} is out of bounds of `{s_trunc}`{ellipsis}");
      }
  
      // 2. begin <= end
      assert!(
          begin <= end,
          "begin <= end ({} <= {}) when slicing `{}`{}",
          begin,
          end,
          s_trunc,
          ellipsis
      );
  
      // 3. character boundary
      let index = if !s.is_char_boundary(begin) { begin } else { end };
      // find the character
      let char_start = s.floor_char_boundary(index);
      // `char_start` must be less than len and a char boundary
      let ch = s[char_start..].chars().next().unwrap();
      let char_range = char_start..char_start + ch.len_utf8();
      panic!(
          "byte index {} is not a char boundary; it is inside {:?} (bytes {:?}) of `{}`{}",
          index, ch, char_range, s_trunc, ellipsis
      );
  }
  *)
  Definition slice_error_fail_rt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ s; begin; end_ ] =>
      ltac:(M.monadic
        (let s := M.alloc (| s |) in
        let begin := M.alloc (| begin |) in
        let end_ := M.alloc (| end_ |) in
        M.read (|
          let~ trunc_len :=
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (| Ty.path "str", "floor_char_boundary", [] |),
                [
                  M.read (| s |);
                  M.read (|
                    M.get_constant (| "core::str::slice_error_fail_rt::MAX_DISPLAY_LENGTH" |)
                  |)
                ]
              |)
            |) in
          let~ s_trunc :=
            M.alloc (|
              M.call_closure (|
                M.get_trait_method (|
                  "core::ops::index::Index",
                  Ty.path "str",
                  [ Ty.apply (Ty.path "core::ops::range::RangeTo") [] [ Ty.path "usize" ] ],
                  "index",
                  []
                |),
                [
                  M.read (| s |);
                  Value.StructRecord
                    "core::ops::range::RangeTo"
                    [ ("end_", M.read (| trunc_len |)) ]
                ]
              |)
            |) in
          let~ ellipsis :=
            M.copy (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            BinOp.lt (|
                              M.read (| trunc_len |),
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "str", "len", [] |),
                                [ M.read (| s |) ]
                              |)
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      Value.String "[...]"));
                  fun γ => ltac:(M.monadic (M.alloc (| M.read (| Value.String "" |) |)))
                ]
              |)
            |) in
          let~ _ :=
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.gt (|
                              M.read (| begin |),
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "str", "len", [] |),
                                [ M.read (| s |) ]
                              |)
                            |),
                            ltac:(M.monadic
                              (BinOp.gt (|
                                M.read (| end_ |),
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "len", [] |),
                                  [ M.read (| s |) ]
                                |)
                              |)))
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.never_to_any (|
                        M.read (|
                          let~ oob_index :=
                            M.copy (|
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            BinOp.gt (|
                                              M.read (| begin |),
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "str",
                                                  "len",
                                                  []
                                                |),
                                                [ M.read (| s |) ]
                                              |)
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      begin));
                                  fun γ => ltac:(M.monadic end_)
                                ]
                              |)
                            |) in
                          M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::panicking::panic_fmt", [] |),
                              [
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "core::fmt::Arguments",
                                    "new_v1",
                                    []
                                  |),
                                  [
                                    M.alloc (|
                                      Value.Array
                                        [
                                          M.read (| Value.String "byte index " |);
                                          M.read (| Value.String " is out of bounds of `" |);
                                          M.read (| Value.String "`" |)
                                        ]
                                    |);
                                    M.alloc (|
                                      Value.Array
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "core::fmt::rt::Argument",
                                              "new_display",
                                              [ Ty.path "usize" ]
                                            |),
                                            [ oob_index ]
                                          |);
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "core::fmt::rt::Argument",
                                              "new_display",
                                              [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                                            |),
                                            [ s_trunc ]
                                          |);
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "core::fmt::rt::Argument",
                                              "new_display",
                                              [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                                            |),
                                            [ ellipsis ]
                                          |)
                                        ]
                                    |)
                                  ]
                                |)
                              ]
                            |)
                          |)
                        |)
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
              ]
            |) in
          let~ _ :=
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          UnOp.not (| BinOp.le (| M.read (| begin |), M.read (| end_ |) |) |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (| "core::panicking::panic_fmt", [] |),
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "core::fmt::Arguments",
                                "new_v1",
                                []
                              |),
                              [
                                M.alloc (|
                                  Value.Array
                                    [
                                      M.read (| Value.String "begin <= end (" |);
                                      M.read (| Value.String " <= " |);
                                      M.read (| Value.String ") when slicing `" |);
                                      M.read (| Value.String "`" |)
                                    ]
                                |);
                                M.alloc (|
                                  Value.Array
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "core::fmt::rt::Argument",
                                          "new_display",
                                          [ Ty.path "usize" ]
                                        |),
                                        [ begin ]
                                      |);
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "core::fmt::rt::Argument",
                                          "new_display",
                                          [ Ty.path "usize" ]
                                        |),
                                        [ end_ ]
                                      |);
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "core::fmt::rt::Argument",
                                          "new_display",
                                          [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                                        |),
                                        [ s_trunc ]
                                      |);
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "core::fmt::rt::Argument",
                                          "new_display",
                                          [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                                        |),
                                        [ ellipsis ]
                                      |)
                                    ]
                                |)
                              ]
                            |)
                          ]
                        |)
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
              ]
            |) in
          let~ index :=
            M.copy (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "str",
                                  "is_char_boundary",
                                  []
                                |),
                                [ M.read (| s |); M.read (| begin |) ]
                              |)
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      begin));
                  fun γ => ltac:(M.monadic end_)
                ]
              |)
            |) in
          let~ char_start :=
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (| Ty.path "str", "floor_char_boundary", [] |),
                [ M.read (| s |); M.read (| index |) ]
              |)
            |) in
          let~ ch :=
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::option::Option") [] [ Ty.path "char" ],
                  "unwrap",
                  []
                |),
                [
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::iter::traits::iterator::Iterator",
                      Ty.path "core::str::iter::Chars",
                      [],
                      "next",
                      []
                    |),
                    [
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "str", "chars", [] |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::ops::index::Index",
                                Ty.path "str",
                                [
                                  Ty.apply
                                    (Ty.path "core::ops::range::RangeFrom")
                                    []
                                    [ Ty.path "usize" ]
                                ],
                                "index",
                                []
                              |),
                              [
                                M.read (| s |);
                                Value.StructRecord
                                  "core::ops::range::RangeFrom"
                                  [ ("start", M.read (| char_start |)) ]
                              ]
                            |)
                          ]
                        |)
                      |)
                    ]
                  |)
                ]
              |)
            |) in
          let~ char_range :=
            M.alloc (|
              Value.StructRecord
                "core::ops::range::Range"
                [
                  ("start", M.read (| char_start |));
                  ("end_",
                    BinOp.Wrap.add (|
                      M.read (| char_start |),
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "char", "len_utf8", [] |),
                        [ M.read (| ch |) ]
                      |)
                    |))
                ]
            |) in
          M.alloc (|
            M.call_closure (|
              M.get_function (| "core::panicking::panic_fmt", [] |),
              [
                M.call_closure (|
                  M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_v1", [] |),
                  [
                    M.alloc (|
                      Value.Array
                        [
                          M.read (| Value.String "byte index " |);
                          M.read (| Value.String " is not a char boundary; it is inside " |);
                          M.read (| Value.String " (bytes " |);
                          M.read (| Value.String ") of `" |);
                          M.read (| Value.String "`" |)
                        ]
                    |);
                    M.alloc (|
                      Value.Array
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::rt::Argument",
                              "new_display",
                              [ Ty.path "usize" ]
                            |),
                            [ index ]
                          |);
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::rt::Argument",
                              "new_debug",
                              [ Ty.path "char" ]
                            |),
                            [ ch ]
                          |);
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::rt::Argument",
                              "new_debug",
                              [ Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ]
                              ]
                            |),
                            [ char_range ]
                          |);
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::rt::Argument",
                              "new_display",
                              [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                            |),
                            [ s_trunc ]
                          |);
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::rt::Argument",
                              "new_display",
                              [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                            |),
                            [ ellipsis ]
                          |)
                        ]
                    |)
                  ]
                |)
              ]
            |)
          |)
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_slice_error_fail_rt :
    M.IsFunction "core::str::slice_error_fail_rt" slice_error_fail_rt.
  
  Module slice_error_fail_rt.
    Definition value_MAX_DISPLAY_LENGTH : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.Usize 256 |))).
  End slice_error_fail_rt.
  
  Module Impl_str.
    Definition Self : Ty.t := Ty.path "str".
    
    (*
        pub const fn len(&self) -> usize {
            self.as_bytes().len()
        }
    *)
    Definition len (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
              "len",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_len : M.IsAssociatedFunction Self "len" len.
    
    (*
        pub const fn is_empty(&self) -> bool {
            self.len() == 0
        }
    *)
    Definition is_empty (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.eq (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "str", "len", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.Usize 0
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_empty : M.IsAssociatedFunction Self "is_empty" is_empty.
    
    (*
        pub fn is_char_boundary(&self, index: usize) -> bool {
            // 0 is always ok.
            // Test for 0 explicitly so that it can optimize out the check
            // easily and skip reading string data for that case.
            // Note that optimizing `self.get(..index)` relies on this.
            if index == 0 {
                return true;
            }
    
            match self.as_bytes().get(index) {
                // For `None` we have two options:
                //
                // - index == self.len()
                //   Empty strings are valid, so return true
                // - index > self.len()
                //   In this case return false
                //
                // The check is placed exactly here, because it improves generated
                // code on higher opt-levels. See PR #84751 for more details.
                None => index == self.len(),
    
                Some(&b) => b.is_utf8_char_boundary(),
            }
        }
    *)
    Definition is_char_boundary (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; index ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let index := M.alloc (| index |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| index |), Value.Integer IntegerKind.Usize 0 |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (| M.read (| M.return_ (| Value.Bool true |) |) |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                M.match_operator (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                        "get",
                        [ Ty.path "usize" ]
                      |),
                      [
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                          [ M.read (| self |) ]
                        |);
                        M.read (| index |)
                      ]
                    |)
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                        M.alloc (|
                          BinOp.eq (|
                            M.read (| index |),
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "len", [] |),
                              [ M.read (| self |) ]
                            |)
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ,
                            "core::option::Option::Some",
                            0
                          |) in
                        let γ0_0 := M.read (| γ0_0 |) in
                        let b := M.copy (| γ0_0 |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "u8",
                              "is_utf8_char_boundary",
                              []
                            |),
                            [ M.read (| b |) ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_char_boundary :
      M.IsAssociatedFunction Self "is_char_boundary" is_char_boundary.
    
    (*
        pub fn floor_char_boundary(&self, index: usize) -> usize {
            if index >= self.len() {
                self.len()
            } else {
                let lower_bound = index.saturating_sub(3);
                let new_index = self.as_bytes()[lower_bound..=index]
                    .iter()
                    .rposition(|b| b.is_utf8_char_boundary());
    
                // SAFETY: we know that the character boundary will be within four bytes
                unsafe { lower_bound + new_index.unwrap_unchecked() }
            }
        }
    *)
    Definition floor_char_boundary (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; index ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let index := M.alloc (| index |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ge (|
                            M.read (| index |),
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "len", [] |),
                              [ M.read (| self |) ]
                            |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "str", "len", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let~ lower_bound :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "usize", "saturating_sub", [] |),
                          [ M.read (| index |); Value.Integer IntegerKind.Usize 3 ]
                        |)
                      |) in
                    let~ new_index :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::iter::traits::iterator::Iterator",
                            Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "u8" ],
                            [],
                            "rposition",
                            [
                              Ty.function
                                [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ Ty.path "u8" ] ] ]
                                (Ty.path "bool")
                            ]
                          |),
                          [
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                  "iter",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::index::Index",
                                      Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                      [
                                        Ty.apply
                                          (Ty.path "core::ops::range::RangeInclusive")
                                          []
                                          [ Ty.path "usize" ]
                                      ],
                                      "index",
                                      []
                                    |),
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "str",
                                          "as_bytes",
                                          []
                                        |),
                                        [ M.read (| self |) ]
                                      |);
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "core::ops::range::RangeInclusive")
                                            []
                                            [ Ty.path "usize" ],
                                          "new",
                                          []
                                        |),
                                        [ M.read (| lower_bound |); M.read (| index |) ]
                                      |)
                                    ]
                                  |)
                                ]
                              |)
                            |);
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [ α0 ] =>
                                    ltac:(M.monadic
                                      (M.match_operator (|
                                        M.alloc (| α0 |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let b := M.copy (| γ |) in
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u8",
                                                  "is_utf8_char_boundary",
                                                  []
                                                |),
                                                [ M.read (| M.read (| b |) |) ]
                                              |)))
                                        ]
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          ]
                        |)
                      |) in
                    M.alloc (|
                      BinOp.Wrap.add (|
                        M.read (| lower_bound |),
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "core::option::Option") [] [ Ty.path "usize" ],
                            "unwrap_unchecked",
                            []
                          |),
                          [ M.read (| new_index |) ]
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_floor_char_boundary :
      M.IsAssociatedFunction Self "floor_char_boundary" floor_char_boundary.
    
    (*
        pub fn ceil_char_boundary(&self, index: usize) -> usize {
            if index > self.len() {
                self.len()
            } else {
                let upper_bound = Ord::min(index + 4, self.len());
                self.as_bytes()[index..upper_bound]
                    .iter()
                    .position(|b| b.is_utf8_char_boundary())
                    .map_or(upper_bound, |pos| pos + index)
            }
        }
    *)
    Definition ceil_char_boundary (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; index ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let index := M.alloc (| index |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (|
                            M.read (| index |),
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "len", [] |),
                              [ M.read (| self |) ]
                            |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "str", "len", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let~ upper_bound :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (| "core::cmp::Ord", Ty.path "usize", [], "min", [] |),
                          [
                            BinOp.Wrap.add (|
                              M.read (| index |),
                              Value.Integer IntegerKind.Usize 4
                            |);
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "len", [] |),
                              [ M.read (| self |) ]
                            |)
                          ]
                        |)
                      |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "core::option::Option") [] [ Ty.path "usize" ],
                          "map_or",
                          [
                            Ty.path "usize";
                            Ty.function [ Ty.tuple [ Ty.path "usize" ] ] (Ty.path "usize")
                          ]
                        |),
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "u8" ],
                              [],
                              "position",
                              [
                                Ty.function
                                  [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ Ty.path "u8" ] ] ]
                                  (Ty.path "bool")
                              ]
                            |),
                            [
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                    "iter",
                                    []
                                  |),
                                  [
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::index::Index",
                                        Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::ops::range::Range")
                                            []
                                            [ Ty.path "usize" ]
                                        ],
                                        "index",
                                        []
                                      |),
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "str",
                                            "as_bytes",
                                            []
                                          |),
                                          [ M.read (| self |) ]
                                        |);
                                        Value.StructRecord
                                          "core::ops::range::Range"
                                          [
                                            ("start", M.read (| index |));
                                            ("end_", M.read (| upper_bound |))
                                          ]
                                      ]
                                    |)
                                  ]
                                |)
                              |);
                              M.closure
                                (fun γ =>
                                  ltac:(M.monadic
                                    match γ with
                                    | [ α0 ] =>
                                      ltac:(M.monadic
                                        (M.match_operator (|
                                          M.alloc (| α0 |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let b := M.copy (| γ |) in
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "u8",
                                                    "is_utf8_char_boundary",
                                                    []
                                                  |),
                                                  [ M.read (| M.read (| b |) |) ]
                                                |)))
                                          ]
                                        |)))
                                    | _ => M.impossible "wrong number of arguments"
                                    end))
                            ]
                          |);
                          M.read (| upper_bound |);
                          M.closure
                            (fun γ =>
                              ltac:(M.monadic
                                match γ with
                                | [ α0 ] =>
                                  ltac:(M.monadic
                                    (M.match_operator (|
                                      M.alloc (| α0 |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let pos := M.copy (| γ |) in
                                            BinOp.Wrap.add (|
                                              M.read (| pos |),
                                              M.read (| index |)
                                            |)))
                                      ]
                                    |)))
                                | _ => M.impossible "wrong number of arguments"
                                end))
                        ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ceil_char_boundary :
      M.IsAssociatedFunction Self "ceil_char_boundary" ceil_char_boundary.
    
    (*
        pub const fn as_bytes(&self) -> &[u8] {
            // SAFETY: const sound because we transmute two types with the same layout
            unsafe { mem::transmute(self) }
        }
    *)
    Definition as_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "&") [] [ Ty.path "str" ];
                Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ] ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_bytes : M.IsAssociatedFunction Self "as_bytes" as_bytes.
    
    (*
        pub const unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
            // SAFETY: the cast from `&str` to `&[u8]` is safe since `str`
            // has the same layout as `&[u8]` (only std can make this guarantee).
            // The pointer dereference is safe since it comes from a mutable reference which
            // is guaranteed to be valid for writes.
            unsafe { &mut *(self as *mut str as *mut [u8]) }
        }
    *)
    Definition as_bytes_mut (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| M.use (M.alloc (| M.read (| self |) |)) |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_bytes_mut : M.IsAssociatedFunction Self "as_bytes_mut" as_bytes_mut.
    
    (*
        pub const fn as_ptr(&self) -> *const u8 {
            self as *const str as *const u8
        }
    *)
    Definition as_ptr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| M.use (M.alloc (| M.read (| self |) |)) |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_ptr : M.IsAssociatedFunction Self "as_ptr" as_ptr.
    
    (*
        pub const fn as_mut_ptr(&mut self) -> *mut u8 {
            self as *mut str as *mut u8
        }
    *)
    Definition as_mut_ptr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| M.use (M.alloc (| M.read (| self |) |)) |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_mut_ptr : M.IsAssociatedFunction Self "as_mut_ptr" as_mut_ptr.
    
    (*
        pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
            i.get(self)
        }
    *)
    Definition get (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ _ as I ], [ self; i ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let i := M.alloc (| i |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::slice::index::SliceIndex",
              I,
              [ Ty.path "str" ],
              "get",
              []
            |),
            [ M.read (| i |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_get : M.IsAssociatedFunction Self "get" get.
    
    (*
        pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
            i.get_mut(self)
        }
    *)
    Definition get_mut (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ _ as I ], [ self; i ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let i := M.alloc (| i |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::slice::index::SliceIndex",
              I,
              [ Ty.path "str" ],
              "get_mut",
              []
            |),
            [ M.read (| i |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_get_mut : M.IsAssociatedFunction Self "get_mut" get_mut.
    
    (*
        pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
            // SAFETY: the caller must uphold the safety contract for `get_unchecked`;
            // the slice is dereferenceable because `self` is a safe reference.
            // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
            unsafe { &*i.get_unchecked(self) }
        }
    *)
    Definition get_unchecked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ _ as I ], [ self; i ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let i := M.alloc (| i |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::slice::index::SliceIndex",
              I,
              [ Ty.path "str" ],
              "get_unchecked",
              []
            |),
            [ M.read (| i |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_get_unchecked :
      M.IsAssociatedFunction Self "get_unchecked" get_unchecked.
    
    (*
        pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
            // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`;
            // the slice is dereferenceable because `self` is a safe reference.
            // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
            unsafe { &mut *i.get_unchecked_mut(self) }
        }
    *)
    Definition get_unchecked_mut (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ _ as I ], [ self; i ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let i := M.alloc (| i |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::slice::index::SliceIndex",
              I,
              [ Ty.path "str" ],
              "get_unchecked_mut",
              []
            |),
            [ M.read (| i |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_get_unchecked_mut :
      M.IsAssociatedFunction Self "get_unchecked_mut" get_unchecked_mut.
    
    (*
        pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
            // SAFETY: the caller must uphold the safety contract for `get_unchecked`;
            // the slice is dereferenceable because `self` is a safe reference.
            // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
            unsafe { &*(begin..end).get_unchecked(self) }
        }
    *)
    Definition slice_unchecked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; begin; end_ ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let begin := M.alloc (| begin |) in
          let end_ := M.alloc (| end_ |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::slice::index::SliceIndex",
              Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ],
              [ Ty.path "str" ],
              "get_unchecked",
              []
            |),
            [
              Value.StructRecord
                "core::ops::range::Range"
                [ ("start", M.read (| begin |)); ("end_", M.read (| end_ |)) ];
              M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_slice_unchecked :
      M.IsAssociatedFunction Self "slice_unchecked" slice_unchecked.
    
    (*
        pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
            // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`;
            // the slice is dereferenceable because `self` is a safe reference.
            // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
            unsafe { &mut *(begin..end).get_unchecked_mut(self) }
        }
    *)
    Definition slice_mut_unchecked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; begin; end_ ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let begin := M.alloc (| begin |) in
          let end_ := M.alloc (| end_ |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::slice::index::SliceIndex",
              Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ],
              [ Ty.path "str" ],
              "get_unchecked_mut",
              []
            |),
            [
              Value.StructRecord
                "core::ops::range::Range"
                [ ("start", M.read (| begin |)); ("end_", M.read (| end_ |)) ];
              M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_slice_mut_unchecked :
      M.IsAssociatedFunction Self "slice_mut_unchecked" slice_mut_unchecked.
    
    (*
        pub fn split_at(&self, mid: usize) -> (&str, &str) {
            match self.split_at_checked(mid) {
                None => slice_error_fail(self, 0, mid),
                Some(pair) => pair,
            }
        }
    *)
    Definition split_at (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; mid ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let mid := M.alloc (| mid |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "split_at_checked", [] |),
                  [ M.read (| self |); M.read (| mid |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (| "core::str::slice_error_fail", [] |),
                          [ M.read (| self |); Value.Integer IntegerKind.Usize 0; M.read (| mid |) ]
                        |)
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let pair_ := M.copy (| γ0_0 |) in
                    pair_))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_at : M.IsAssociatedFunction Self "split_at" split_at.
    
    (*
        pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
            // is_char_boundary checks that the index is in [0, .len()]
            if self.is_char_boundary(mid) {
                // SAFETY: just checked that `mid` is on a char boundary.
                unsafe { self.split_at_mut_unchecked(mid) }
            } else {
                slice_error_fail(self, 0, mid)
            }
        }
    *)
    Definition split_at_mut (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; mid ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let mid := M.alloc (| mid |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "str", "is_char_boundary", [] |),
                            [ M.read (| self |); M.read (| mid |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "str", "split_at_mut_unchecked", [] |),
                        [ M.read (| self |); M.read (| mid |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (| "core::str::slice_error_fail", [] |),
                          [ M.read (| self |); Value.Integer IntegerKind.Usize 0; M.read (| mid |) ]
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_at_mut : M.IsAssociatedFunction Self "split_at_mut" split_at_mut.
    
    (*
        pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
            // is_char_boundary checks that the index is in [0, .len()]
            if self.is_char_boundary(mid) {
                // SAFETY: just checked that `mid` is on a char boundary.
                Some(unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) })
            } else {
                None
            }
        }
    *)
    Definition split_at_checked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; mid ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let mid := M.alloc (| mid |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "str", "is_char_boundary", [] |),
                            [ M.read (| self |); M.read (| mid |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          Value.Tuple
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "str",
                                  "get_unchecked",
                                  [
                                    Ty.apply
                                      (Ty.path "core::ops::range::Range")
                                      []
                                      [ Ty.path "usize" ]
                                  ]
                                |),
                                [
                                  M.read (| self |);
                                  Value.StructRecord
                                    "core::ops::range::Range"
                                    [
                                      ("start", Value.Integer IntegerKind.Usize 0);
                                      ("end_", M.read (| mid |))
                                    ]
                                ]
                              |);
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "str",
                                  "get_unchecked",
                                  [
                                    Ty.apply
                                      (Ty.path "core::ops::range::Range")
                                      []
                                      [ Ty.path "usize" ]
                                  ]
                                |),
                                [
                                  M.read (| self |);
                                  Value.StructRecord
                                    "core::ops::range::Range"
                                    [
                                      ("start", M.read (| mid |));
                                      ("end_",
                                        M.call_closure (|
                                          M.get_associated_function (| Ty.path "str", "len", [] |),
                                          [ M.read (| self |) ]
                                        |))
                                    ]
                                ]
                              |)
                            ]
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_at_checked :
      M.IsAssociatedFunction Self "split_at_checked" split_at_checked.
    
    (*
        pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
            // is_char_boundary checks that the index is in [0, .len()]
            if self.is_char_boundary(mid) {
                // SAFETY: just checked that `mid` is on a char boundary.
                Some(unsafe { self.split_at_mut_unchecked(mid) })
            } else {
                None
            }
        }
    *)
    Definition split_at_mut_checked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; mid ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let mid := M.alloc (| mid |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "str", "is_char_boundary", [] |),
                            [ M.read (| self |); M.read (| mid |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "str",
                              "split_at_mut_unchecked",
                              []
                            |),
                            [ M.read (| self |); M.read (| mid |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_at_mut_checked :
      M.IsAssociatedFunction Self "split_at_mut_checked" split_at_mut_checked.
    
    (*
        unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
            let len = self.len();
            let ptr = self.as_mut_ptr();
            // SAFETY: caller guarantees `mid` is on a char boundary.
            unsafe {
                (
                    from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)),
                    from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr.add(mid), len - mid)),
                )
            }
        }
    *)
    Definition split_at_mut_unchecked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; mid ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let mid := M.alloc (| mid |) in
          M.read (|
            let~ len :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "len", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ ptr :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "as_mut_ptr", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.call_closure (|
                    M.get_function (| "core::str::converts::from_utf8_unchecked_mut", [] |),
                    [
                      M.call_closure (|
                        M.get_function (|
                          "core::slice::raw::from_raw_parts_mut",
                          [ Ty.path "u8" ]
                        |),
                        [ M.read (| ptr |); M.read (| mid |) ]
                      |)
                    ]
                  |);
                  M.call_closure (|
                    M.get_function (| "core::str::converts::from_utf8_unchecked_mut", [] |),
                    [
                      M.call_closure (|
                        M.get_function (|
                          "core::slice::raw::from_raw_parts_mut",
                          [ Ty.path "u8" ]
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "*mut") [] [ Ty.path "u8" ],
                              "add",
                              []
                            |),
                            [ M.read (| ptr |); M.read (| mid |) ]
                          |);
                          BinOp.Wrap.sub (| M.read (| len |), M.read (| mid |) |)
                        ]
                      |)
                    ]
                  |)
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_at_mut_unchecked :
      M.IsAssociatedFunction Self "split_at_mut_unchecked" split_at_mut_unchecked.
    
    (*
        pub fn chars(&self) -> Chars<'_> {
            Chars { iter: self.as_bytes().iter() }
        }
    *)
    Definition chars (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructRecord
            "core::str::iter::Chars"
            [
              ("iter",
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                    "iter",
                    []
                  |),
                  [
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| self |) ]
                    |)
                  ]
                |))
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_chars : M.IsAssociatedFunction Self "chars" chars.
    
    (*
        pub fn char_indices(&self) -> CharIndices<'_> {
            CharIndices { front_offset: 0, iter: self.chars() }
        }
    *)
    Definition char_indices (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructRecord
            "core::str::iter::CharIndices"
            [
              ("front_offset", Value.Integer IntegerKind.Usize 0);
              ("iter",
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "chars", [] |),
                  [ M.read (| self |) ]
                |))
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_char_indices : M.IsAssociatedFunction Self "char_indices" char_indices.
    
    (*
        pub fn bytes(&self) -> Bytes<'_> {
            Bytes(self.as_bytes().iter().copied())
        }
    *)
    Definition bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple
            "core::str::iter::Bytes"
            [
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::iterator::Iterator",
                  Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "u8" ],
                  [],
                  "copied",
                  [ Ty.path "u8" ]
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                      "iter",
                      []
                    |),
                    [
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                        [ M.read (| self |) ]
                      |)
                    ]
                  |)
                ]
              |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_bytes : M.IsAssociatedFunction Self "bytes" bytes.
    
    (*
        pub fn split_whitespace(&self) -> SplitWhitespace<'_> {
            SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) }
        }
    *)
    Definition split_whitespace (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructRecord
            "core::str::iter::SplitWhitespace"
            [
              ("inner",
                M.call_closure (|
                  M.get_trait_method (|
                    "core::iter::traits::iterator::Iterator",
                    Ty.apply
                      (Ty.path "core::str::iter::Split")
                      []
                      [ Ty.path "core::str::IsWhitespace" ],
                    [],
                    "filter",
                    [ Ty.path "core::str::IsNotEmpty" ]
                  |),
                  [
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "str",
                        "split",
                        [ Ty.path "core::str::IsWhitespace" ]
                      |),
                      [ M.read (| self |); Value.StructTuple "core::str::IsWhitespace" [] ]
                    |);
                    Value.StructTuple "core::str::IsNotEmpty" []
                  ]
                |))
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_whitespace :
      M.IsAssociatedFunction Self "split_whitespace" split_whitespace.
    
    (*
        pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> {
            let inner =
                self.as_bytes().split(IsAsciiWhitespace).filter(BytesIsNotEmpty).map(UnsafeBytesToStr);
            SplitAsciiWhitespace { inner }
        }
    *)
    Definition split_ascii_whitespace (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ inner :=
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "core::iter::traits::iterator::Iterator",
                    Ty.apply
                      (Ty.path "core::iter::adapters::filter::Filter")
                      []
                      [
                        Ty.apply
                          (Ty.path "core::slice::iter::Split")
                          []
                          [ Ty.path "u8"; Ty.path "core::str::IsAsciiWhitespace" ];
                        Ty.path "core::str::BytesIsNotEmpty"
                      ],
                    [],
                    "map",
                    [
                      Ty.apply (Ty.path "&") [] [ Ty.path "str" ];
                      Ty.path "core::str::UnsafeBytesToStr"
                    ]
                  |),
                  [
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::iter::traits::iterator::Iterator",
                        Ty.apply
                          (Ty.path "core::slice::iter::Split")
                          []
                          [ Ty.path "u8"; Ty.path "core::str::IsAsciiWhitespace" ],
                        [],
                        "filter",
                        [ Ty.path "core::str::BytesIsNotEmpty" ]
                      |),
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                            "split",
                            [ Ty.path "core::str::IsAsciiWhitespace" ]
                          |),
                          [
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                              [ M.read (| self |) ]
                            |);
                            Value.StructTuple "core::str::IsAsciiWhitespace" []
                          ]
                        |);
                        Value.StructTuple "core::str::BytesIsNotEmpty" []
                      ]
                    |);
                    Value.StructTuple "core::str::UnsafeBytesToStr" []
                  ]
                |)
              |) in
            M.alloc (|
              Value.StructRecord
                "core::str::iter::SplitAsciiWhitespace"
                [ ("inner", M.read (| inner |)) ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_ascii_whitespace :
      M.IsAssociatedFunction Self "split_ascii_whitespace" split_ascii_whitespace.
    
    (*
        pub fn lines(&self) -> Lines<'_> {
            Lines(self.split_inclusive('\n').map(LinesMap))
        }
    *)
    Definition lines (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple
            "core::str::iter::Lines"
            [
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::iterator::Iterator",
                  Ty.apply (Ty.path "core::str::iter::SplitInclusive") [] [ Ty.path "char" ],
                  [],
                  "map",
                  [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ]; Ty.path "core::str::LinesMap" ]
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "str",
                      "split_inclusive",
                      [ Ty.path "char" ]
                    |),
                    [ M.read (| self |); Value.UnicodeChar 10 ]
                  |);
                  Value.StructTuple "core::str::LinesMap" []
                ]
              |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_lines : M.IsAssociatedFunction Self "lines" lines.
    
    (*
        pub fn lines_any(&self) -> LinesAny<'_> {
            LinesAny(self.lines())
        }
    *)
    Definition lines_any (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple
            "core::str::iter::LinesAny"
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "str", "lines", [] |),
                [ M.read (| self |) ]
              |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_lines_any : M.IsAssociatedFunction Self "lines_any" lines_any.
    
    (*
        pub fn encode_utf16(&self) -> EncodeUtf16<'_> {
            EncodeUtf16 { chars: self.chars(), extra: 0 }
        }
    *)
    Definition encode_utf16 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructRecord
            "core::str::iter::EncodeUtf16"
            [
              ("chars",
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "chars", [] |),
                  [ M.read (| self |) ]
                |));
              ("extra", Value.Integer IntegerKind.U16 0)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_encode_utf16 : M.IsAssociatedFunction Self "encode_utf16" encode_utf16.
    
    (*
        pub fn contains<P: Pattern>(&self, pat: P) -> bool {
            pat.is_contained_in(self)
        }
    *)
    Definition contains (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          M.call_closure (|
            M.get_trait_method (| "core::str::pattern::Pattern", P, [], "is_contained_in", [] |),
            [ M.read (| pat |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_contains : M.IsAssociatedFunction Self "contains" contains.
    
    (*
        pub fn starts_with<P: Pattern>(&self, pat: P) -> bool {
            pat.is_prefix_of(self)
        }
    *)
    Definition starts_with (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          M.call_closure (|
            M.get_trait_method (| "core::str::pattern::Pattern", P, [], "is_prefix_of", [] |),
            [ M.read (| pat |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_starts_with : M.IsAssociatedFunction Self "starts_with" starts_with.
    
    (*
        pub fn ends_with<P: Pattern>(&self, pat: P) -> bool
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            pat.is_suffix_of(self)
        }
    *)
    Definition ends_with (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          M.call_closure (|
            M.get_trait_method (| "core::str::pattern::Pattern", P, [], "is_suffix_of", [] |),
            [ M.read (| pat |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ends_with : M.IsAssociatedFunction Self "ends_with" ends_with.
    
    (*
        pub fn find<P: Pattern>(&self, pat: P) -> Option<usize> {
            pat.into_searcher(self).next_match().map(|(i, _)| i)
        }
    *)
    Definition find (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply
                (Ty.path "core::option::Option")
                []
                [ Ty.tuple [ Ty.path "usize"; Ty.path "usize" ] ],
              "map",
              [
                Ty.path "usize";
                Ty.function
                  [ Ty.tuple [ Ty.tuple [ Ty.path "usize"; Ty.path "usize" ] ] ]
                  (Ty.path "usize")
              ]
            |),
            [
              M.call_closure (|
                M.get_trait_method (|
                  "core::str::pattern::Searcher",
                  Ty.associated,
                  [],
                  "next_match",
                  []
                |),
                [
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::str::pattern::Pattern",
                        P,
                        [],
                        "into_searcher",
                        []
                      |),
                      [ M.read (| pat |); M.read (| self |) ]
                    |)
                  |)
                ]
              |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                let i := M.copy (| γ0_0 |) in
                                M.read (| i |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_find : M.IsAssociatedFunction Self "find" find.
    
    (*
        pub fn rfind<P: Pattern>(&self, pat: P) -> Option<usize>
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            pat.into_searcher(self).next_match_back().map(|(i, _)| i)
        }
    *)
    Definition rfind (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply
                (Ty.path "core::option::Option")
                []
                [ Ty.tuple [ Ty.path "usize"; Ty.path "usize" ] ],
              "map",
              [
                Ty.path "usize";
                Ty.function
                  [ Ty.tuple [ Ty.tuple [ Ty.path "usize"; Ty.path "usize" ] ] ]
                  (Ty.path "usize")
              ]
            |),
            [
              M.call_closure (|
                M.get_trait_method (|
                  "core::str::pattern::ReverseSearcher",
                  Ty.associated,
                  [],
                  "next_match_back",
                  []
                |),
                [
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::str::pattern::Pattern",
                        P,
                        [],
                        "into_searcher",
                        []
                      |),
                      [ M.read (| pat |); M.read (| self |) ]
                    |)
                  |)
                ]
              |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                let i := M.copy (| γ0_0 |) in
                                M.read (| i |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rfind : M.IsAssociatedFunction Self "rfind" rfind.
    
    (*
        pub fn split<P: Pattern>(&self, pat: P) -> Split<'_, P> {
            Split(SplitInternal {
                start: 0,
                end: self.len(),
                matcher: pat.into_searcher(self),
                allow_trailing_empty: true,
                finished: false,
            })
        }
    *)
    Definition split (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::Split"
            [
              Value.StructRecord
                "core::str::iter::SplitInternal"
                [
                  ("start", Value.Integer IntegerKind.Usize 0);
                  ("end_",
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "len", [] |),
                      [ M.read (| self |) ]
                    |));
                  ("matcher",
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::str::pattern::Pattern",
                        P,
                        [],
                        "into_searcher",
                        []
                      |),
                      [ M.read (| pat |); M.read (| self |) ]
                    |));
                  ("allow_trailing_empty", Value.Bool true);
                  ("finished", Value.Bool false)
                ]
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split : M.IsAssociatedFunction Self "split" split.
    
    (*
        pub fn split_inclusive<P: Pattern>(&self, pat: P) -> SplitInclusive<'_, P> {
            SplitInclusive(SplitInternal {
                start: 0,
                end: self.len(),
                matcher: pat.into_searcher(self),
                allow_trailing_empty: false,
                finished: false,
            })
        }
    *)
    Definition split_inclusive (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::SplitInclusive"
            [
              Value.StructRecord
                "core::str::iter::SplitInternal"
                [
                  ("start", Value.Integer IntegerKind.Usize 0);
                  ("end_",
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "len", [] |),
                      [ M.read (| self |) ]
                    |));
                  ("matcher",
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::str::pattern::Pattern",
                        P,
                        [],
                        "into_searcher",
                        []
                      |),
                      [ M.read (| pat |); M.read (| self |) ]
                    |));
                  ("allow_trailing_empty", Value.Bool false);
                  ("finished", Value.Bool false)
                ]
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_inclusive :
      M.IsAssociatedFunction Self "split_inclusive" split_inclusive.
    
    (*
        pub fn rsplit<P: Pattern>(&self, pat: P) -> RSplit<'_, P>
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            RSplit(self.split(pat).0)
        }
    *)
    Definition rsplit (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::RSplit"
            [
              M.read (|
                M.SubPointer.get_struct_tuple_field (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "split", [ P ] |),
                      [ M.read (| self |); M.read (| pat |) ]
                    |)
                  |),
                  "core::str::iter::Split",
                  0
                |)
              |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rsplit : M.IsAssociatedFunction Self "rsplit" rsplit.
    
    (*
        pub fn split_terminator<P: Pattern>(&self, pat: P) -> SplitTerminator<'_, P> {
            SplitTerminator(SplitInternal { allow_trailing_empty: false, ..self.split(pat).0 })
        }
    *)
    Definition split_terminator (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::SplitTerminator"
            [
              M.struct_record_update
                (M.read (|
                  M.SubPointer.get_struct_tuple_field (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "str", "split", [ P ] |),
                        [ M.read (| self |); M.read (| pat |) ]
                      |)
                    |),
                    "core::str::iter::Split",
                    0
                  |)
                |))
                [ ("allow_trailing_empty", Value.Bool false) ]
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_terminator :
      M.IsAssociatedFunction Self "split_terminator" split_terminator.
    
    (*
        pub fn rsplit_terminator<P: Pattern>(&self, pat: P) -> RSplitTerminator<'_, P>
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            RSplitTerminator(self.split_terminator(pat).0)
        }
    *)
    Definition rsplit_terminator (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::RSplitTerminator"
            [
              M.read (|
                M.SubPointer.get_struct_tuple_field (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "split_terminator", [ P ] |),
                      [ M.read (| self |); M.read (| pat |) ]
                    |)
                  |),
                  "core::str::iter::SplitTerminator",
                  0
                |)
              |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rsplit_terminator :
      M.IsAssociatedFunction Self "rsplit_terminator" rsplit_terminator.
    
    (*
        pub fn splitn<P: Pattern>(&self, n: usize, pat: P) -> SplitN<'_, P> {
            SplitN(SplitNInternal { iter: self.split(pat).0, count: n })
        }
    *)
    Definition splitn (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; n; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::SplitN"
            [
              Value.StructRecord
                "core::str::iter::SplitNInternal"
                [
                  ("iter",
                    M.read (|
                      M.SubPointer.get_struct_tuple_field (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "str", "split", [ P ] |),
                            [ M.read (| self |); M.read (| pat |) ]
                          |)
                        |),
                        "core::str::iter::Split",
                        0
                      |)
                    |));
                  ("count", M.read (| n |))
                ]
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_splitn : M.IsAssociatedFunction Self "splitn" splitn.
    
    (*
        pub fn rsplitn<P: Pattern>(&self, n: usize, pat: P) -> RSplitN<'_, P>
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            RSplitN(self.splitn(n, pat).0)
        }
    *)
    Definition rsplitn (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; n; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::RSplitN"
            [
              M.read (|
                M.SubPointer.get_struct_tuple_field (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "splitn", [ P ] |),
                      [ M.read (| self |); M.read (| n |); M.read (| pat |) ]
                    |)
                  |),
                  "core::str::iter::SplitN",
                  0
                |)
              |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rsplitn : M.IsAssociatedFunction Self "rsplitn" rsplitn.
    
    (*
        pub fn split_once<P: Pattern>(&self, delimiter: P) -> Option<(&'_ str, &'_ str)> {
            let (start, end) = delimiter.into_searcher(self).next_match()?;
            // SAFETY: `Searcher` is known to return valid indices.
            unsafe { Some((self.get_unchecked(..start), self.get_unchecked(end..))) }
        }
    *)
    Definition split_once (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; delimiter ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let delimiter := M.alloc (| delimiter |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                M.match_operator (|
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::ops::try_trait::Try",
                          Ty.apply
                            (Ty.path "core::option::Option")
                            []
                            [ Ty.tuple [ Ty.path "usize"; Ty.path "usize" ] ],
                          [],
                          "branch",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::str::pattern::Searcher",
                              Ty.associated,
                              [],
                              "next_match",
                              []
                            |),
                            [
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::str::pattern::Pattern",
                                    P,
                                    [],
                                    "into_searcher",
                                    []
                                  |),
                                  [ M.read (| delimiter |); M.read (| self |) ]
                                |)
                              |)
                            ]
                          |)
                        ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::ops::control_flow::ControlFlow::Break",
                              0
                            |) in
                          let residual := M.copy (| γ0_0 |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.return_ (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::try_trait::FromResidual",
                                      Ty.apply
                                        (Ty.path "core::option::Option")
                                        []
                                        [
                                          Ty.tuple
                                            [
                                              Ty.apply (Ty.path "&") [] [ Ty.path "str" ];
                                              Ty.apply (Ty.path "&") [] [ Ty.path "str" ]
                                            ]
                                        ],
                                      [
                                        Ty.apply
                                          (Ty.path "core::option::Option")
                                          []
                                          [ Ty.path "core::convert::Infallible" ]
                                      ],
                                      "from_residual",
                                      []
                                    |),
                                    [ M.read (| residual |) ]
                                  |)
                                |)
                              |)
                            |)
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::ops::control_flow::ControlFlow::Continue",
                              0
                            |) in
                          let val := M.copy (| γ0_0 |) in
                          val))
                    ]
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                        let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                        let start := M.copy (| γ0_0 |) in
                        let end_ := M.copy (| γ0_1 |) in
                        M.alloc (|
                          Value.StructTuple
                            "core::option::Option::Some"
                            [
                              Value.Tuple
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "str",
                                      "get_unchecked",
                                      [
                                        Ty.apply
                                          (Ty.path "core::ops::range::RangeTo")
                                          []
                                          [ Ty.path "usize" ]
                                      ]
                                    |),
                                    [
                                      M.read (| self |);
                                      Value.StructRecord
                                        "core::ops::range::RangeTo"
                                        [ ("end_", M.read (| start |)) ]
                                    ]
                                  |);
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "str",
                                      "get_unchecked",
                                      [
                                        Ty.apply
                                          (Ty.path "core::ops::range::RangeFrom")
                                          []
                                          [ Ty.path "usize" ]
                                      ]
                                    |),
                                    [
                                      M.read (| self |);
                                      Value.StructRecord
                                        "core::ops::range::RangeFrom"
                                        [ ("start", M.read (| end_ |)) ]
                                    ]
                                  |)
                                ]
                            ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_once : M.IsAssociatedFunction Self "split_once" split_once.
    
    (*
        pub fn rsplit_once<P: Pattern>(&self, delimiter: P) -> Option<(&'_ str, &'_ str)>
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            let (start, end) = delimiter.into_searcher(self).next_match_back()?;
            // SAFETY: `Searcher` is known to return valid indices.
            unsafe { Some((self.get_unchecked(..start), self.get_unchecked(end..))) }
        }
    *)
    Definition rsplit_once (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; delimiter ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let delimiter := M.alloc (| delimiter |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                M.match_operator (|
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::ops::try_trait::Try",
                          Ty.apply
                            (Ty.path "core::option::Option")
                            []
                            [ Ty.tuple [ Ty.path "usize"; Ty.path "usize" ] ],
                          [],
                          "branch",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::str::pattern::ReverseSearcher",
                              Ty.associated,
                              [],
                              "next_match_back",
                              []
                            |),
                            [
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::str::pattern::Pattern",
                                    P,
                                    [],
                                    "into_searcher",
                                    []
                                  |),
                                  [ M.read (| delimiter |); M.read (| self |) ]
                                |)
                              |)
                            ]
                          |)
                        ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::ops::control_flow::ControlFlow::Break",
                              0
                            |) in
                          let residual := M.copy (| γ0_0 |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.return_ (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::try_trait::FromResidual",
                                      Ty.apply
                                        (Ty.path "core::option::Option")
                                        []
                                        [
                                          Ty.tuple
                                            [
                                              Ty.apply (Ty.path "&") [] [ Ty.path "str" ];
                                              Ty.apply (Ty.path "&") [] [ Ty.path "str" ]
                                            ]
                                        ],
                                      [
                                        Ty.apply
                                          (Ty.path "core::option::Option")
                                          []
                                          [ Ty.path "core::convert::Infallible" ]
                                      ],
                                      "from_residual",
                                      []
                                    |),
                                    [ M.read (| residual |) ]
                                  |)
                                |)
                              |)
                            |)
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::ops::control_flow::ControlFlow::Continue",
                              0
                            |) in
                          let val := M.copy (| γ0_0 |) in
                          val))
                    ]
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                        let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                        let start := M.copy (| γ0_0 |) in
                        let end_ := M.copy (| γ0_1 |) in
                        M.alloc (|
                          Value.StructTuple
                            "core::option::Option::Some"
                            [
                              Value.Tuple
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "str",
                                      "get_unchecked",
                                      [
                                        Ty.apply
                                          (Ty.path "core::ops::range::RangeTo")
                                          []
                                          [ Ty.path "usize" ]
                                      ]
                                    |),
                                    [
                                      M.read (| self |);
                                      Value.StructRecord
                                        "core::ops::range::RangeTo"
                                        [ ("end_", M.read (| start |)) ]
                                    ]
                                  |);
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "str",
                                      "get_unchecked",
                                      [
                                        Ty.apply
                                          (Ty.path "core::ops::range::RangeFrom")
                                          []
                                          [ Ty.path "usize" ]
                                      ]
                                    |),
                                    [
                                      M.read (| self |);
                                      Value.StructRecord
                                        "core::ops::range::RangeFrom"
                                        [ ("start", M.read (| end_ |)) ]
                                    ]
                                  |)
                                ]
                            ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rsplit_once : M.IsAssociatedFunction Self "rsplit_once" rsplit_once.
    
    (*
        pub fn matches<P: Pattern>(&self, pat: P) -> Matches<'_, P> {
            Matches(MatchesInternal(pat.into_searcher(self)))
        }
    *)
    Definition matches (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::Matches"
            [
              Value.StructTuple
                "core::str::iter::MatchesInternal"
                [
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::str::pattern::Pattern",
                      P,
                      [],
                      "into_searcher",
                      []
                    |),
                    [ M.read (| pat |); M.read (| self |) ]
                  |)
                ]
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_matches : M.IsAssociatedFunction Self "matches" matches.
    
    (*
        pub fn rmatches<P: Pattern>(&self, pat: P) -> RMatches<'_, P>
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            RMatches(self.matches(pat).0)
        }
    *)
    Definition rmatches (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::RMatches"
            [
              M.read (|
                M.SubPointer.get_struct_tuple_field (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "matches", [ P ] |),
                      [ M.read (| self |); M.read (| pat |) ]
                    |)
                  |),
                  "core::str::iter::Matches",
                  0
                |)
              |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rmatches : M.IsAssociatedFunction Self "rmatches" rmatches.
    
    (*
        pub fn match_indices<P: Pattern>(&self, pat: P) -> MatchIndices<'_, P> {
            MatchIndices(MatchIndicesInternal(pat.into_searcher(self)))
        }
    *)
    Definition match_indices (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::MatchIndices"
            [
              Value.StructTuple
                "core::str::iter::MatchIndicesInternal"
                [
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::str::pattern::Pattern",
                      P,
                      [],
                      "into_searcher",
                      []
                    |),
                    [ M.read (| pat |); M.read (| self |) ]
                  |)
                ]
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_match_indices :
      M.IsAssociatedFunction Self "match_indices" match_indices.
    
    (*
        pub fn rmatch_indices<P: Pattern>(&self, pat: P) -> RMatchIndices<'_, P>
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            RMatchIndices(self.match_indices(pat).0)
        }
    *)
    Definition rmatch_indices (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          Value.StructTuple
            "core::str::iter::RMatchIndices"
            [
              M.read (|
                M.SubPointer.get_struct_tuple_field (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "match_indices", [ P ] |),
                      [ M.read (| self |); M.read (| pat |) ]
                    |)
                  |),
                  "core::str::iter::MatchIndices",
                  0
                |)
              |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rmatch_indices :
      M.IsAssociatedFunction Self "rmatch_indices" rmatch_indices.
    
    (*
        pub fn trim(&self) -> &str {
            self.trim_matches(|c: char| c.is_whitespace())
        }
    *)
    Definition trim (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.path "str",
              "trim_matches",
              [ Ty.function [ Ty.tuple [ Ty.path "char" ] ] (Ty.path "bool") ]
            |),
            [
              M.read (| self |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let c := M.copy (| γ |) in
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "char",
                                    "is_whitespace",
                                    []
                                  |),
                                  [ M.read (| c |) ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim : M.IsAssociatedFunction Self "trim" trim.
    
    (*
        pub fn trim_start(&self) -> &str {
            self.trim_start_matches(|c: char| c.is_whitespace())
        }
    *)
    Definition trim_start (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.path "str",
              "trim_start_matches",
              [ Ty.function [ Ty.tuple [ Ty.path "char" ] ] (Ty.path "bool") ]
            |),
            [
              M.read (| self |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let c := M.copy (| γ |) in
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "char",
                                    "is_whitespace",
                                    []
                                  |),
                                  [ M.read (| c |) ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_start : M.IsAssociatedFunction Self "trim_start" trim_start.
    
    (*
        pub fn trim_end(&self) -> &str {
            self.trim_end_matches(|c: char| c.is_whitespace())
        }
    *)
    Definition trim_end (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.path "str",
              "trim_end_matches",
              [ Ty.function [ Ty.tuple [ Ty.path "char" ] ] (Ty.path "bool") ]
            |),
            [
              M.read (| self |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let c := M.copy (| γ |) in
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "char",
                                    "is_whitespace",
                                    []
                                  |),
                                  [ M.read (| c |) ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_end : M.IsAssociatedFunction Self "trim_end" trim_end.
    
    (*
        pub fn trim_left(&self) -> &str {
            self.trim_start()
        }
    *)
    Definition trim_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "str", "trim_start", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_left : M.IsAssociatedFunction Self "trim_left" trim_left.
    
    (*
        pub fn trim_right(&self) -> &str {
            self.trim_end()
        }
    *)
    Definition trim_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "str", "trim_end", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_right : M.IsAssociatedFunction Self "trim_right" trim_right.
    
    (*
        pub fn trim_matches<P: Pattern>(&self, pat: P) -> &str
        where
            for<'a> P::Searcher<'a>: DoubleEndedSearcher<'a>,
        {
            let mut i = 0;
            let mut j = 0;
            let mut matcher = pat.into_searcher(self);
            if let Some((a, b)) = matcher.next_reject() {
                i = a;
                j = b; // Remember earliest known match, correct it below if
                // last match is different
            }
            if let Some((_, b)) = matcher.next_reject_back() {
                j = b;
            }
            // SAFETY: `Searcher` is known to return valid indices.
            unsafe { self.get_unchecked(i..j) }
        }
    *)
    Definition trim_matches (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          M.read (|
            let~ i := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
            let~ j := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
            let~ matcher :=
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "core::str::pattern::Pattern",
                    P,
                    [],
                    "into_searcher",
                    []
                  |),
                  [ M.read (| pat |); M.read (| self |) ]
                |)
              |) in
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::str::pattern::Searcher",
                              Ty.associated,
                              [],
                              "next_reject",
                              []
                            |),
                            [ matcher ]
                          |)
                        |) in
                      let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::option::Option::Some",
                          0
                        |) in
                      let γ1_0 := M.SubPointer.get_tuple_field (| γ0_0, 0 |) in
                      let γ1_1 := M.SubPointer.get_tuple_field (| γ0_0, 1 |) in
                      let a := M.copy (| γ1_0 |) in
                      let b := M.copy (| γ1_1 |) in
                      let~ _ := M.write (| i, M.read (| a |) |) in
                      let~ _ := M.write (| j, M.read (| b |) |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::str::pattern::ReverseSearcher",
                              Ty.associated,
                              [],
                              "next_reject_back",
                              []
                            |),
                            [ matcher ]
                          |)
                        |) in
                      let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::option::Option::Some",
                          0
                        |) in
                      let γ1_0 := M.SubPointer.get_tuple_field (| γ0_0, 0 |) in
                      let γ1_1 := M.SubPointer.get_tuple_field (| γ0_0, 1 |) in
                      let b := M.copy (| γ1_1 |) in
                      let~ _ := M.write (| j, M.read (| b |) |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "str",
                  "get_unchecked",
                  [ Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ] ]
                |),
                [
                  M.read (| self |);
                  Value.StructRecord
                    "core::ops::range::Range"
                    [ ("start", M.read (| i |)); ("end_", M.read (| j |)) ]
                ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_matches : M.IsAssociatedFunction Self "trim_matches" trim_matches.
    
    (*
        pub fn trim_start_matches<P: Pattern>(&self, pat: P) -> &str {
            let mut i = self.len();
            let mut matcher = pat.into_searcher(self);
            if let Some((a, _)) = matcher.next_reject() {
                i = a;
            }
            // SAFETY: `Searcher` is known to return valid indices.
            unsafe { self.get_unchecked(i..self.len()) }
        }
    *)
    Definition trim_start_matches (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          M.read (|
            let~ i :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "len", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ matcher :=
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "core::str::pattern::Pattern",
                    P,
                    [],
                    "into_searcher",
                    []
                  |),
                  [ M.read (| pat |); M.read (| self |) ]
                |)
              |) in
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::str::pattern::Searcher",
                              Ty.associated,
                              [],
                              "next_reject",
                              []
                            |),
                            [ matcher ]
                          |)
                        |) in
                      let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::option::Option::Some",
                          0
                        |) in
                      let γ1_0 := M.SubPointer.get_tuple_field (| γ0_0, 0 |) in
                      let γ1_1 := M.SubPointer.get_tuple_field (| γ0_0, 1 |) in
                      let a := M.copy (| γ1_0 |) in
                      let~ _ := M.write (| i, M.read (| a |) |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "str",
                  "get_unchecked",
                  [ Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ] ]
                |),
                [
                  M.read (| self |);
                  Value.StructRecord
                    "core::ops::range::Range"
                    [
                      ("start", M.read (| i |));
                      ("end_",
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "str", "len", [] |),
                          [ M.read (| self |) ]
                        |))
                    ]
                ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_start_matches :
      M.IsAssociatedFunction Self "trim_start_matches" trim_start_matches.
    
    (*
        pub fn strip_prefix<P: Pattern>(&self, prefix: P) -> Option<&str> {
            prefix.strip_prefix_of(self)
        }
    *)
    Definition strip_prefix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; prefix ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let prefix := M.alloc (| prefix |) in
          M.call_closure (|
            M.get_trait_method (| "core::str::pattern::Pattern", P, [], "strip_prefix_of", [] |),
            [ M.read (| prefix |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strip_prefix : M.IsAssociatedFunction Self "strip_prefix" strip_prefix.
    
    (*
        pub fn strip_suffix<P: Pattern>(&self, suffix: P) -> Option<&str>
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            suffix.strip_suffix_of(self)
        }
    *)
    Definition strip_suffix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; suffix ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let suffix := M.alloc (| suffix |) in
          M.call_closure (|
            M.get_trait_method (| "core::str::pattern::Pattern", P, [], "strip_suffix_of", [] |),
            [ M.read (| suffix |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strip_suffix : M.IsAssociatedFunction Self "strip_suffix" strip_suffix.
    
    (*
        pub fn trim_end_matches<P: Pattern>(&self, pat: P) -> &str
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            let mut j = 0;
            let mut matcher = pat.into_searcher(self);
            if let Some((_, b)) = matcher.next_reject_back() {
                j = b;
            }
            // SAFETY: `Searcher` is known to return valid indices.
            unsafe { self.get_unchecked(0..j) }
        }
    *)
    Definition trim_end_matches (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          M.read (|
            let~ j := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
            let~ matcher :=
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "core::str::pattern::Pattern",
                    P,
                    [],
                    "into_searcher",
                    []
                  |),
                  [ M.read (| pat |); M.read (| self |) ]
                |)
              |) in
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::str::pattern::ReverseSearcher",
                              Ty.associated,
                              [],
                              "next_reject_back",
                              []
                            |),
                            [ matcher ]
                          |)
                        |) in
                      let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::option::Option::Some",
                          0
                        |) in
                      let γ1_0 := M.SubPointer.get_tuple_field (| γ0_0, 0 |) in
                      let γ1_1 := M.SubPointer.get_tuple_field (| γ0_0, 1 |) in
                      let b := M.copy (| γ1_1 |) in
                      let~ _ := M.write (| j, M.read (| b |) |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "str",
                  "get_unchecked",
                  [ Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ] ]
                |),
                [
                  M.read (| self |);
                  Value.StructRecord
                    "core::ops::range::Range"
                    [ ("start", Value.Integer IntegerKind.Usize 0); ("end_", M.read (| j |)) ]
                ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_end_matches :
      M.IsAssociatedFunction Self "trim_end_matches" trim_end_matches.
    
    (*
        pub fn trim_left_matches<P: Pattern>(&self, pat: P) -> &str {
            self.trim_start_matches(pat)
        }
    *)
    Definition trim_left_matches (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "str", "trim_start_matches", [ P ] |),
            [ M.read (| self |); M.read (| pat |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_left_matches :
      M.IsAssociatedFunction Self "trim_left_matches" trim_left_matches.
    
    (*
        pub fn trim_right_matches<P: Pattern>(&self, pat: P) -> &str
        where
            for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
        {
            self.trim_end_matches(pat)
        }
    *)
    Definition trim_right_matches (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ P ], [ self; pat ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pat := M.alloc (| pat |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "str", "trim_end_matches", [ P ] |),
            [ M.read (| self |); M.read (| pat |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_right_matches :
      M.IsAssociatedFunction Self "trim_right_matches" trim_right_matches.
    
    (*
        pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
            FromStr::from_str(self)
        }
    *)
    Definition parse (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ F ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_trait_method (| "core::str::traits::FromStr", F, [], "from_str", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_parse : M.IsAssociatedFunction Self "parse" parse.
    
    (*
        pub const fn is_ascii(&self) -> bool {
            // We can treat each byte as character here: all multibyte characters
            // start with a byte that is not in the ASCII range, so we will stop
            // there already.
            self.as_bytes().is_ascii()
        }
    *)
    Definition is_ascii (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
              "is_ascii",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii : M.IsAssociatedFunction Self "is_ascii" is_ascii.
    
    (*
        pub const fn as_ascii(&self) -> Option<&[ascii::Char]> {
            // Like in `is_ascii`, we can work on the bytes directly.
            self.as_bytes().as_ascii()
        }
    *)
    Definition as_ascii (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
              "as_ascii",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_ascii : M.IsAssociatedFunction Self "as_ascii" as_ascii.
    
    (*
        pub fn eq_ignore_ascii_case(&self, other: &str) -> bool {
            self.as_bytes().eq_ignore_ascii_case(other.as_bytes())
        }
    *)
    Definition eq_ignore_ascii_case (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
              "eq_ignore_ascii_case",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                [ M.read (| self |) ]
              |);
              M.call_closure (|
                M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                [ M.read (| other |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_eq_ignore_ascii_case :
      M.IsAssociatedFunction Self "eq_ignore_ascii_case" eq_ignore_ascii_case.
    
    (*
        pub const fn make_ascii_uppercase(&mut self) {
            // SAFETY: changing ASCII letters only does not invalidate UTF-8.
            let me = unsafe { self.as_bytes_mut() };
            me.make_ascii_uppercase()
        }
    *)
    Definition make_ascii_uppercase (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ me :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "as_bytes_mut", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                  "make_ascii_uppercase",
                  []
                |),
                [ M.read (| me |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_make_ascii_uppercase :
      M.IsAssociatedFunction Self "make_ascii_uppercase" make_ascii_uppercase.
    
    (*
        pub const fn make_ascii_lowercase(&mut self) {
            // SAFETY: changing ASCII letters only does not invalidate UTF-8.
            let me = unsafe { self.as_bytes_mut() };
            me.make_ascii_lowercase()
        }
    *)
    Definition make_ascii_lowercase (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ me :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "as_bytes_mut", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                  "make_ascii_lowercase",
                  []
                |),
                [ M.read (| me |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_make_ascii_lowercase :
      M.IsAssociatedFunction Self "make_ascii_lowercase" make_ascii_lowercase.
    
    (*
        pub const fn trim_ascii_start(&self) -> &str {
            // SAFETY: Removing ASCII characters from a `&str` does not invalidate
            // UTF-8.
            unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii_start()) }
        }
    *)
    Definition trim_ascii_start (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (| "core::str::converts::from_utf8_unchecked", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                  "trim_ascii_start",
                  []
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                    [ M.read (| self |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_ascii_start :
      M.IsAssociatedFunction Self "trim_ascii_start" trim_ascii_start.
    
    (*
        pub const fn trim_ascii_end(&self) -> &str {
            // SAFETY: Removing ASCII characters from a `&str` does not invalidate
            // UTF-8.
            unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii_end()) }
        }
    *)
    Definition trim_ascii_end (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (| "core::str::converts::from_utf8_unchecked", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                  "trim_ascii_end",
                  []
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                    [ M.read (| self |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_ascii_end :
      M.IsAssociatedFunction Self "trim_ascii_end" trim_ascii_end.
    
    (*
        pub const fn trim_ascii(&self) -> &str {
            // SAFETY: Removing ASCII characters from a `&str` does not invalidate
            // UTF-8.
            unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii()) }
        }
    *)
    Definition trim_ascii (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (| "core::str::converts::from_utf8_unchecked", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                  "trim_ascii",
                  []
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                    [ M.read (| self |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trim_ascii : M.IsAssociatedFunction Self "trim_ascii" trim_ascii.
    
    (*
        pub fn escape_debug(&self) -> EscapeDebug<'_> {
            let mut chars = self.chars();
            EscapeDebug {
                inner: chars
                    .next()
                    .map(|first| first.escape_debug_ext(EscapeDebugExtArgs::ESCAPE_ALL))
                    .into_iter()
                    .flatten()
                    .chain(chars.flat_map(CharEscapeDebugContinue)),
            }
        }
    *)
    Definition escape_debug (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ chars :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "chars", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            M.alloc (|
              Value.StructRecord
                "core::str::iter::EscapeDebug"
                [
                  ("inner",
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::iter::traits::iterator::Iterator",
                        Ty.apply
                          (Ty.path "core::iter::adapters::flatten::Flatten")
                          []
                          [
                            Ty.apply
                              (Ty.path "core::option::IntoIter")
                              []
                              [ Ty.path "core::char::EscapeDebug" ]
                          ],
                        [],
                        "chain",
                        [
                          Ty.apply
                            (Ty.path "core::iter::adapters::flatten::FlatMap")
                            []
                            [
                              Ty.path "core::str::iter::Chars";
                              Ty.path "core::char::EscapeDebug";
                              Ty.path "core::str::CharEscapeDebugContinue"
                            ]
                        ]
                      |),
                      [
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::iter::traits::iterator::Iterator",
                            Ty.apply
                              (Ty.path "core::option::IntoIter")
                              []
                              [ Ty.path "core::char::EscapeDebug" ],
                            [],
                            "flatten",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::collect::IntoIterator",
                                Ty.apply
                                  (Ty.path "core::option::Option")
                                  []
                                  [ Ty.path "core::char::EscapeDebug" ],
                                [],
                                "into_iter",
                                []
                              |),
                              [
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "core::option::Option") [] [ Ty.path "char" ],
                                    "map",
                                    [
                                      Ty.path "core::char::EscapeDebug";
                                      Ty.function
                                        [ Ty.tuple [ Ty.path "char" ] ]
                                        (Ty.path "core::char::EscapeDebug")
                                    ]
                                  |),
                                  [
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::iterator::Iterator",
                                        Ty.path "core::str::iter::Chars",
                                        [],
                                        "next",
                                        []
                                      |),
                                      [ chars ]
                                    |);
                                    M.closure
                                      (fun γ =>
                                        ltac:(M.monadic
                                          match γ with
                                          | [ α0 ] =>
                                            ltac:(M.monadic
                                              (M.match_operator (|
                                                M.alloc (| α0 |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let first := M.copy (| γ |) in
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.path "char",
                                                          "escape_debug_ext",
                                                          []
                                                        |),
                                                        [
                                                          M.read (| first |);
                                                          M.read (|
                                                            M.get_constant (|
                                                              "core::char::methods::ESCAPE_ALL"
                                                            |)
                                                          |)
                                                        ]
                                                      |)))
                                                ]
                                              |)))
                                          | _ => M.impossible "wrong number of arguments"
                                          end))
                                  ]
                                |)
                              ]
                            |)
                          ]
                        |);
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::iter::traits::iterator::Iterator",
                            Ty.path "core::str::iter::Chars",
                            [],
                            "flat_map",
                            [
                              Ty.path "core::char::EscapeDebug";
                              Ty.path "core::str::CharEscapeDebugContinue"
                            ]
                          |),
                          [
                            M.read (| chars |);
                            Value.StructTuple "core::str::CharEscapeDebugContinue" []
                          ]
                        |)
                      ]
                    |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_escape_debug : M.IsAssociatedFunction Self "escape_debug" escape_debug.
    
    (*
        pub fn escape_default(&self) -> EscapeDefault<'_> {
            EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) }
        }
    *)
    Definition escape_default (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructRecord
            "core::str::iter::EscapeDefault"
            [
              ("inner",
                M.call_closure (|
                  M.get_trait_method (|
                    "core::iter::traits::iterator::Iterator",
                    Ty.path "core::str::iter::Chars",
                    [],
                    "flat_map",
                    [ Ty.path "core::char::EscapeDefault"; Ty.path "core::str::CharEscapeDefault" ]
                  |),
                  [
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "chars", [] |),
                      [ M.read (| self |) ]
                    |);
                    Value.StructTuple "core::str::CharEscapeDefault" []
                  ]
                |))
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_escape_default :
      M.IsAssociatedFunction Self "escape_default" escape_default.
    
    (*
        pub fn escape_unicode(&self) -> EscapeUnicode<'_> {
            EscapeUnicode { inner: self.chars().flat_map(CharEscapeUnicode) }
        }
    *)
    Definition escape_unicode (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructRecord
            "core::str::iter::EscapeUnicode"
            [
              ("inner",
                M.call_closure (|
                  M.get_trait_method (|
                    "core::iter::traits::iterator::Iterator",
                    Ty.path "core::str::iter::Chars",
                    [],
                    "flat_map",
                    [ Ty.path "core::char::EscapeUnicode"; Ty.path "core::str::CharEscapeUnicode" ]
                  |),
                  [
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "chars", [] |),
                      [ M.read (| self |) ]
                    |);
                    Value.StructTuple "core::str::CharEscapeUnicode" []
                  ]
                |))
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_escape_unicode :
      M.IsAssociatedFunction Self "escape_unicode" escape_unicode.
    
    (*
        pub fn substr_range(&self, substr: &str) -> Option<Range<usize>> {
            self.as_bytes().subslice_range(substr.as_bytes())
        }
    *)
    Definition substr_range (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; substr ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let substr := M.alloc (| substr |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
              "subslice_range",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                [ M.read (| self |) ]
              |);
              M.call_closure (|
                M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                [ M.read (| substr |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_substr_range : M.IsAssociatedFunction Self "substr_range" substr_range.
    
    (*
        pub fn as_str(&self) -> &str {
            self
        }
    *)
    Definition as_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_str : M.IsAssociatedFunction Self "as_str" as_str.
  End Impl_str.
  
  Module Impl_core_convert_AsRef_slice_u8_for_str.
    Definition Self : Ty.t := Ty.path "str".
    
    (*
        fn as_ref(&self) -> &[u8] {
            self.as_bytes()
        }
    *)
    Definition as_ref (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::convert::AsRef"
        Self
        (* Trait polymorphic types *) [ (* T *) Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ] ]
        (* Instance *) [ ("as_ref", InstanceField.Method as_ref) ].
  End Impl_core_convert_AsRef_slice_u8_for_str.
  
  Module Impl_core_default_Default_for_ref__str.
    Definition Self : Ty.t := Ty.apply (Ty.path "&") [] [ Ty.path "str" ].
    
    (*
        fn default() -> Self {
            ""
        }
    *)
    Definition default (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| Value.String "" |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::default::Default"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("default", InstanceField.Method default) ].
  End Impl_core_default_Default_for_ref__str.
  
  Module Impl_core_default_Default_for_ref_mut_str.
    Definition Self : Ty.t := Ty.apply (Ty.path "&mut") [] [ Ty.path "str" ].
    
    (*
        fn default() -> Self {
            // SAFETY: The empty string is valid UTF-8.
            unsafe { from_utf8_unchecked_mut(&mut []) }
        }
    *)
    Definition default (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::str::converts::from_utf8_unchecked_mut", [] |),
            [ M.alloc (| Value.Array [] |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::default::Default"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("default", InstanceField.Method default) ].
  End Impl_core_default_Default_for_ref_mut_str.
  
  Module Impl_core_clone_Clone_for_core_str_LinesMap.
    Definition Self : Ty.t := Ty.path "core::str::LinesMap".
    
    (*     Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple "core::str::LinesMap" []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_core_str_LinesMap.
  
  Module Impl_core_clone_Clone_for_core_str_CharEscapeDebugContinue.
    Definition Self : Ty.t := Ty.path "core::str::CharEscapeDebugContinue".
    
    (*     Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple "core::str::CharEscapeDebugContinue" []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_core_str_CharEscapeDebugContinue.
  
  Module Impl_core_clone_Clone_for_core_str_CharEscapeUnicode.
    Definition Self : Ty.t := Ty.path "core::str::CharEscapeUnicode".
    
    (*     Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple "core::str::CharEscapeUnicode" []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_core_str_CharEscapeUnicode.
  
  Module Impl_core_clone_Clone_for_core_str_CharEscapeDefault.
    Definition Self : Ty.t := Ty.path "core::str::CharEscapeDefault".
    
    (*     Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple "core::str::CharEscapeDefault" []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_core_str_CharEscapeDefault.
  
  Module Impl_core_clone_Clone_for_core_str_IsWhitespace.
    Definition Self : Ty.t := Ty.path "core::str::IsWhitespace".
    
    (*     Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple "core::str::IsWhitespace" []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_core_str_IsWhitespace.
  
  Module Impl_core_clone_Clone_for_core_str_IsAsciiWhitespace.
    Definition Self : Ty.t := Ty.path "core::str::IsAsciiWhitespace".
    
    (*     Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple "core::str::IsAsciiWhitespace" []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_core_str_IsAsciiWhitespace.
  
  Module Impl_core_clone_Clone_for_core_str_IsNotEmpty.
    Definition Self : Ty.t := Ty.path "core::str::IsNotEmpty".
    
    (*     Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple "core::str::IsNotEmpty" []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_core_str_IsNotEmpty.
  
  Module Impl_core_clone_Clone_for_core_str_BytesIsNotEmpty.
    Definition Self : Ty.t := Ty.path "core::str::BytesIsNotEmpty".
    
    (*     Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple "core::str::BytesIsNotEmpty" []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_core_str_BytesIsNotEmpty.
  
  Module Impl_core_clone_Clone_for_core_str_UnsafeBytesToStr.
    Definition Self : Ty.t := Ty.path "core::str::UnsafeBytesToStr".
    
    (*     Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.StructTuple "core::str::UnsafeBytesToStr" []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_core_str_UnsafeBytesToStr.
  
  Module Impl_core_error_Error_for_ref__str.
    Definition Self : Ty.t := Ty.apply (Ty.path "&") [] [ Ty.path "str" ].
    
    Axiom Implements :
      M.IsTraitInstance
        "core::error::Error"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [].
  End Impl_core_error_Error_for_ref__str.
End str.
