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

Module slice.
  (*
  fn split_point_of(range: impl OneSidedRange<usize>) -> Option<(Direction, usize)> {
      use Bound::*;
  
      Some(match (range.start_bound(), range.end_bound()) {
          (Unbounded, Excluded(i)) => (Direction::Front, *i),
          (Unbounded, Included(i)) => (Direction::Front, i.checked_add(1)?),
          (Excluded(i), Unbounded) => (Direction::Back, i.checked_add(1)?),
          (Included(i), Unbounded) => (Direction::Back, *i),
          _ => unreachable!(),
      })
  }
  *)
  Definition split_point_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [ impl_OneSidedRange_usize_ ], [ range ] =>
      ltac:(M.monadic
        (let range := M.alloc (| range |) in
        M.catch_return (|
          ltac:(M.monadic
            (Value.StructTuple
              "core::option::Option::Some"
              [
                M.read (|
                  M.match_operator (|
                    M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::ops::range::RangeBounds",
                              impl_OneSidedRange_usize_,
                              [ Ty.path "usize" ],
                              "start_bound",
                              []
                            |),
                            [ range ]
                          |);
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::ops::range::RangeBounds",
                              impl_OneSidedRange_usize_,
                              [ Ty.path "usize" ],
                              "end_bound",
                              []
                            |),
                            [ range ]
                          |)
                        ]
                    |),
                    [
                      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 _ :=
                            M.is_struct_tuple (| γ0_0, "core::ops::range::Bound::Unbounded" |) in
                          let γ1_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ0_1,
                              "core::ops::range::Bound::Excluded",
                              0
                            |) in
                          let i := M.copy (| γ1_0 |) in
                          M.alloc (|
                            Value.Tuple
                              [
                                Value.StructTuple "core::slice::Direction::Front" [];
                                M.read (| M.read (| i |) |)
                              ]
                          |)));
                      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 _ :=
                            M.is_struct_tuple (| γ0_0, "core::ops::range::Bound::Unbounded" |) in
                          let γ1_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ0_1,
                              "core::ops::range::Bound::Included",
                              0
                            |) in
                          let i := M.copy (| γ1_0 |) in
                          M.alloc (|
                            Value.Tuple
                              [
                                Value.StructTuple "core::slice::Direction::Front" [];
                                M.read (|
                                  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.path "usize" ],
                                          [],
                                          "branch",
                                          []
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "usize",
                                              "checked_add",
                                              []
                                            |),
                                            [
                                              M.read (| M.read (| i |) |);
                                              Value.Integer IntegerKind.Usize 1
                                            ]
                                          |)
                                        ]
                                      |)
                                    |),
                                    [
                                      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.path "core::slice::Direction";
                                                              Ty.path "usize"
                                                            ]
                                                        ],
                                                      [
                                                        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 γ1_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ0_0,
                              "core::ops::range::Bound::Excluded",
                              0
                            |) in
                          let i := M.copy (| γ1_0 |) in
                          let _ :=
                            M.is_struct_tuple (| γ0_1, "core::ops::range::Bound::Unbounded" |) in
                          M.alloc (|
                            Value.Tuple
                              [
                                Value.StructTuple "core::slice::Direction::Back" [];
                                M.read (|
                                  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.path "usize" ],
                                          [],
                                          "branch",
                                          []
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "usize",
                                              "checked_add",
                                              []
                                            |),
                                            [
                                              M.read (| M.read (| i |) |);
                                              Value.Integer IntegerKind.Usize 1
                                            ]
                                          |)
                                        ]
                                      |)
                                    |),
                                    [
                                      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.path "core::slice::Direction";
                                                              Ty.path "usize"
                                                            ]
                                                        ],
                                                      [
                                                        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 γ1_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ0_0,
                              "core::ops::range::Bound::Included",
                              0
                            |) in
                          let i := M.copy (| γ1_0 |) in
                          let _ :=
                            M.is_struct_tuple (| γ0_1, "core::ops::range::Bound::Unbounded" |) in
                          M.alloc (|
                            Value.Tuple
                              [
                                Value.StructTuple "core::slice::Direction::Back" [];
                                M.read (| M.read (| i |) |)
                              ]
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (|
                            M.never_to_any (|
                              M.call_closure (|
                                M.get_function (| "core::panicking::panic", [] |),
                                [
                                  M.read (|
                                    Value.String "internal error: entered unreachable code"
                                  |)
                                ]
                              |)
                            |)
                          |)))
                    ]
                  |)
                |)
              ]))
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_split_point_of : M.IsFunction "core::slice::split_point_of" split_point_of.
  
  (*
  Enum Direction
  {
    const_params := [];
    ty_params := [];
    variants :=
      [
        {
          name := "Front";
          item := StructTuple [];
          discriminant := None;
        };
        {
          name := "Back";
          item := StructTuple [];
          discriminant := None;
        }
      ];
  }
  *)
  
  Module Impl_slice_T.
    Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "slice") [] [ T ].
    
    (*
        pub const fn len(&self) -> usize {
            ptr::metadata(self)
        }
    *)
    Definition len (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::ptr::metadata::metadata",
              [ Ty.apply (Ty.path "slice") [] [ T ] ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_len : forall (T : Ty.t), M.IsAssociatedFunction (Self T) "len" (len T).
    
    (*
        pub const fn is_empty(&self) -> bool {
            self.len() == 0
        }
    *)
    Definition is_empty (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.eq (|
            M.call_closure (|
              M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "len", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.Usize 0
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_empty :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "is_empty" (is_empty T).
    
    (*
        pub const fn first(&self) -> Option<&T> {
            if let [first, ..] = self { Some(first) } else { None }
        }
    *)
    Definition first (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := self in
                    let γ := M.read (| γ |) in
                    let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                    let γ1_rest := M.SubPointer.get_slice_rest (| γ, 1, 0 |) in
                    let first := M.alloc (| γ1_0 |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| first |) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_first :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "first" (first T).
    
    (*
        pub const fn first_mut(&mut self) -> Option<&mut T> {
            if let [first, ..] = self { Some(first) } else { None }
        }
    *)
    Definition first_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := self in
                    let γ := M.read (| γ |) in
                    let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                    let γ1_rest := M.SubPointer.get_slice_rest (| γ, 1, 0 |) in
                    let first := M.alloc (| γ1_0 |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| first |) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_first_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "first_mut" (first_mut T).
    
    (*
        pub const fn split_first(&self) -> Option<(&T, &[T])> {
            if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
        }
    *)
    Definition split_first (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := self in
                    let γ := M.read (| γ |) in
                    let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                    let γ1_rest := M.SubPointer.get_slice_rest (| γ, 1, 0 |) in
                    let first := M.alloc (| γ1_0 |) in
                    let tail := M.alloc (| γ1_rest |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [ Value.Tuple [ M.read (| first |); M.read (| tail |) ] ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_first :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_first" (split_first T).
    
    (*
        pub const fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
            if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
        }
    *)
    Definition split_first_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := self in
                    let γ := M.read (| γ |) in
                    let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                    let γ1_rest := M.SubPointer.get_slice_rest (| γ, 1, 0 |) in
                    let first := M.alloc (| γ1_0 |) in
                    let tail := M.alloc (| γ1_rest |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [ Value.Tuple [ M.read (| first |); M.read (| tail |) ] ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_first_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_first_mut" (split_first_mut T).
    
    (*
        pub const fn split_last(&self) -> Option<(&T, &[T])> {
            if let [init @ .., last] = self { Some((last, init)) } else { None }
        }
    *)
    Definition split_last (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := self in
                    let γ := M.read (| γ |) in
                    let γ1_rest := M.SubPointer.get_slice_rest (| γ, 0, 1 |) in
                    let γ1_rev0 := M.SubPointer.get_slice_rev_index (| γ, 0 |) in
                    let init := M.alloc (| γ1_rest |) in
                    let last := M.alloc (| γ1_rev0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [ Value.Tuple [ M.read (| last |); M.read (| init |) ] ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_last :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_last" (split_last T).
    
    (*
        pub const fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
            if let [init @ .., last] = self { Some((last, init)) } else { None }
        }
    *)
    Definition split_last_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := self in
                    let γ := M.read (| γ |) in
                    let γ1_rest := M.SubPointer.get_slice_rest (| γ, 0, 1 |) in
                    let γ1_rev0 := M.SubPointer.get_slice_rev_index (| γ, 0 |) in
                    let init := M.alloc (| γ1_rest |) in
                    let last := M.alloc (| γ1_rev0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [ Value.Tuple [ M.read (| last |); M.read (| init |) ] ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_last_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_last_mut" (split_last_mut T).
    
    (*
        pub const fn last(&self) -> Option<&T> {
            if let [.., last] = self { Some(last) } else { None }
        }
    *)
    Definition last (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := self in
                    let γ := M.read (| γ |) in
                    let γ1_rest := M.SubPointer.get_slice_rest (| γ, 0, 1 |) in
                    let γ1_rev0 := M.SubPointer.get_slice_rev_index (| γ, 0 |) in
                    let last := M.alloc (| γ1_rev0 |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| last |) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_last :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "last" (last T).
    
    (*
        pub const fn last_mut(&mut self) -> Option<&mut T> {
            if let [.., last] = self { Some(last) } else { None }
        }
    *)
    Definition last_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := self in
                    let γ := M.read (| γ |) in
                    let γ1_rest := M.SubPointer.get_slice_rest (| γ, 0, 1 |) in
                    let γ1_rev0 := M.SubPointer.get_slice_rev_index (| γ, 0 |) in
                    let last := M.alloc (| γ1_rev0 |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| last |) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_last_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "last_mut" (last_mut T).
    
    (*
        pub const fn first_chunk<const N: usize>(&self) -> Option<&[T; N]> {
            if self.len() < N {
                None
            } else {
                // SAFETY: We explicitly check for the correct number of elements,
                //   and do not let the reference outlive the slice.
                Some(unsafe { &*(self.as_ptr().cast::<[T; N]>()) })
            }
        }
    *)
    Definition first_chunk (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "len",
                                []
                              |),
                              [ M.read (| self |) ]
                            |),
                            M.read (| M.get_constant (| "core::slice::first_chunk::N" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "*const") [] [ T ],
                              "cast",
                              [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "as_ptr",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |)
                            ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_first_chunk :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "first_chunk" (first_chunk T).
    
    (*
        pub const fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {
            if self.len() < N {
                None
            } else {
                // SAFETY: We explicitly check for the correct number of elements,
                //   do not let the reference outlive the slice,
                //   and require exclusive access to the entire slice to mutate the chunk.
                Some(unsafe { &mut *(self.as_mut_ptr().cast::<[T; N]>()) })
            }
        }
    *)
    Definition first_chunk_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "len",
                                []
                              |),
                              [ M.read (| self |) ]
                            |),
                            M.read (| M.get_constant (| "core::slice::first_chunk_mut::N" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "*mut") [] [ T ],
                              "cast",
                              [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "as_mut_ptr",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |)
                            ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_first_chunk_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "first_chunk_mut" (first_chunk_mut T).
    
    (*
        pub const fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])> {
            if self.len() < N {
                None
            } else {
                // SAFETY: We manually verified the bounds of the split.
                let (first, tail) = unsafe { self.split_at_unchecked(N) };
    
                // SAFETY: We explicitly check for the correct number of elements,
                //   and do not let the references outlive the slice.
                Some((unsafe { &*(first.as_ptr().cast::<[T; N]>()) }, tail))
            }
        }
    *)
    Definition split_first_chunk
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "len",
                                []
                              |),
                              [ M.read (| self |) ]
                            |),
                            M.read (| M.get_constant (| "core::slice::split_first_chunk::N" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "split_at_unchecked",
                            []
                          |),
                          [
                            M.read (| self |);
                            M.read (| M.get_constant (| "core::slice::split_first_chunk::N" |) |)
                          ]
                        |)
                      |),
                      [
                        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 first := M.copy (| γ0_0 |) in
                            let tail := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::option::Option::Some"
                                [
                                  Value.Tuple
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "*const") [] [ T ],
                                          "cast",
                                          [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ T ],
                                              "as_ptr",
                                              []
                                            |),
                                            [ M.read (| first |) ]
                                          |)
                                        ]
                                      |);
                                      M.read (| tail |)
                                    ]
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_first_chunk :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_first_chunk" (split_first_chunk T).
    
    (*
        pub const fn split_first_chunk_mut<const N: usize>(
            &mut self,
        ) -> Option<(&mut [T; N], &mut [T])> {
            if self.len() < N {
                None
            } else {
                // SAFETY: We manually verified the bounds of the split.
                let (first, tail) = unsafe { self.split_at_mut_unchecked(N) };
    
                // SAFETY: We explicitly check for the correct number of elements,
                //   do not let the reference outlive the slice,
                //   and enforce exclusive mutability of the chunk by the split.
                Some((unsafe { &mut *(first.as_mut_ptr().cast::<[T; N]>()) }, tail))
            }
        }
    *)
    Definition split_first_chunk_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "len",
                                []
                              |),
                              [ M.read (| self |) ]
                            |),
                            M.read (|
                              M.get_constant (| "core::slice::split_first_chunk_mut::N" |)
                            |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "split_at_mut_unchecked",
                            []
                          |),
                          [
                            M.read (| self |);
                            M.read (|
                              M.get_constant (| "core::slice::split_first_chunk_mut::N" |)
                            |)
                          ]
                        |)
                      |),
                      [
                        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 first := M.copy (| γ0_0 |) in
                            let tail := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::option::Option::Some"
                                [
                                  Value.Tuple
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "*mut") [] [ T ],
                                          "cast",
                                          [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ T ],
                                              "as_mut_ptr",
                                              []
                                            |),
                                            [ M.read (| first |) ]
                                          |)
                                        ]
                                      |);
                                      M.read (| tail |)
                                    ]
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_first_chunk_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_first_chunk_mut" (split_first_chunk_mut T).
    
    (*
        pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])> {
            if self.len() < N {
                None
            } else {
                // SAFETY: We manually verified the bounds of the split.
                let (init, last) = unsafe { self.split_at_unchecked(self.len() - N) };
    
                // SAFETY: We explicitly check for the correct number of elements,
                //   and do not let the references outlive the slice.
                Some((init, unsafe { &*(last.as_ptr().cast::<[T; N]>()) }))
            }
        }
    *)
    Definition split_last_chunk
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "len",
                                []
                              |),
                              [ M.read (| self |) ]
                            |),
                            M.read (| M.get_constant (| "core::slice::split_last_chunk::N" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "split_at_unchecked",
                            []
                          |),
                          [
                            M.read (| self |);
                            BinOp.Wrap.sub (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "len",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |),
                              M.read (| M.get_constant (| "core::slice::split_last_chunk::N" |) |)
                            |)
                          ]
                        |)
                      |),
                      [
                        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 init := M.copy (| γ0_0 |) in
                            let last := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::option::Option::Some"
                                [
                                  Value.Tuple
                                    [
                                      M.read (| init |);
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "*const") [] [ T ],
                                          "cast",
                                          [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ T ],
                                              "as_ptr",
                                              []
                                            |),
                                            [ M.read (| last |) ]
                                          |)
                                        ]
                                      |)
                                    ]
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_last_chunk :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_last_chunk" (split_last_chunk T).
    
    (*
        pub const fn split_last_chunk_mut<const N: usize>(
            &mut self,
        ) -> Option<(&mut [T], &mut [T; N])> {
            if self.len() < N {
                None
            } else {
                // SAFETY: We manually verified the bounds of the split.
                let (init, last) = unsafe { self.split_at_mut_unchecked(self.len() - N) };
    
                // SAFETY: We explicitly check for the correct number of elements,
                //   do not let the reference outlive the slice,
                //   and enforce exclusive mutability of the chunk by the split.
                Some((init, unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) }))
            }
        }
    *)
    Definition split_last_chunk_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "len",
                                []
                              |),
                              [ M.read (| self |) ]
                            |),
                            M.read (| M.get_constant (| "core::slice::split_last_chunk_mut::N" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "split_at_mut_unchecked",
                            []
                          |),
                          [
                            M.read (| self |);
                            BinOp.Wrap.sub (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "len",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |),
                              M.read (|
                                M.get_constant (| "core::slice::split_last_chunk_mut::N" |)
                              |)
                            |)
                          ]
                        |)
                      |),
                      [
                        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 init := M.copy (| γ0_0 |) in
                            let last := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::option::Option::Some"
                                [
                                  Value.Tuple
                                    [
                                      M.read (| init |);
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "*mut") [] [ T ],
                                          "cast",
                                          [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ T ],
                                              "as_mut_ptr",
                                              []
                                            |),
                                            [ M.read (| last |) ]
                                          |)
                                        ]
                                      |)
                                    ]
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_last_chunk_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_last_chunk_mut" (split_last_chunk_mut T).
    
    (*
        pub const fn last_chunk<const N: usize>(&self) -> Option<&[T; N]> {
            if self.len() < N {
                None
            } else {
                // SAFETY: We manually verified the bounds of the slice.
                // FIXME(const-hack): Without const traits, we need this instead of `get_unchecked`.
                let last = unsafe { self.split_at_unchecked(self.len() - N).1 };
    
                // SAFETY: We explicitly check for the correct number of elements,
                //   and do not let the references outlive the slice.
                Some(unsafe { &*(last.as_ptr().cast::<[T; N]>()) })
            }
        }
    *)
    Definition last_chunk (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "len",
                                []
                              |),
                              [ M.read (| self |) ]
                            |),
                            M.read (| M.get_constant (| "core::slice::last_chunk::N" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)));
                fun γ =>
                  ltac:(M.monadic
                    (let~ last :=
                      M.copy (|
                        M.SubPointer.get_tuple_field (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "split_at_unchecked",
                                []
                              |),
                              [
                                M.read (| self |);
                                BinOp.Wrap.sub (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ T ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |),
                                  M.read (| M.get_constant (| "core::slice::last_chunk::N" |) |)
                                |)
                              ]
                            |)
                          |),
                          1
                        |)
                      |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "*const") [] [ T ],
                              "cast",
                              [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "as_ptr",
                                  []
                                |),
                                [ M.read (| last |) ]
                              |)
                            ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_last_chunk :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "last_chunk" (last_chunk T).
    
    (*
        pub const fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {
            if self.len() < N {
                None
            } else {
                // SAFETY: We manually verified the bounds of the slice.
                // FIXME(const-hack): Without const traits, we need this instead of `get_unchecked`.
                let last = unsafe { self.split_at_mut_unchecked(self.len() - N).1 };
    
                // SAFETY: We explicitly check for the correct number of elements,
                //   do not let the reference outlive the slice,
                //   and require exclusive access to the entire slice to mutate the chunk.
                Some(unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) })
            }
        }
    *)
    Definition last_chunk_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "len",
                                []
                              |),
                              [ M.read (| self |) ]
                            |),
                            M.read (| M.get_constant (| "core::slice::last_chunk_mut::N" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)));
                fun γ =>
                  ltac:(M.monadic
                    (let~ last :=
                      M.alloc (|
                        M.read (|
                          M.SubPointer.get_tuple_field (|
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "split_at_mut_unchecked",
                                  []
                                |),
                                [
                                  M.read (| self |);
                                  BinOp.Wrap.sub (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ T ],
                                        "len",
                                        []
                                      |),
                                      [ M.read (| self |) ]
                                    |),
                                    M.read (|
                                      M.get_constant (| "core::slice::last_chunk_mut::N" |)
                                    |)
                                  |)
                                ]
                              |)
                            |),
                            1
                          |)
                        |)
                      |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "*mut") [] [ T ],
                              "cast",
                              [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "as_mut_ptr",
                                  []
                                |),
                                [ M.read (| last |) ]
                              |)
                            ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_last_chunk_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "last_chunk_mut" (last_chunk_mut T).
    
    (*
        pub fn get<I>(&self, index: I) -> Option<&I::Output>
        where
            I: SliceIndex<Self>,
        {
            index.get(self)
        }
    *)
    Definition get (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ _ as I ], [ self; index ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let index := M.alloc (| index |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::slice::index::SliceIndex",
              I,
              [ Ty.apply (Ty.path "slice") [] [ T ] ],
              "get",
              []
            |),
            [ M.read (| index |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_get : forall (T : Ty.t), M.IsAssociatedFunction (Self T) "get" (get T).
    
    (*
        pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
        where
            I: SliceIndex<Self>,
        {
            index.get_mut(self)
        }
    *)
    Definition get_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ _ as I ], [ self; index ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let index := M.alloc (| index |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::slice::index::SliceIndex",
              I,
              [ Ty.apply (Ty.path "slice") [] [ T ] ],
              "get_mut",
              []
            |),
            [ M.read (| index |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_get_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "get_mut" (get_mut T).
    
    (*
        pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
        where
            I: SliceIndex<Self>,
        {
            // SAFETY: the caller must uphold most of the safety requirements 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 { &*index.get_unchecked(self) }
        }
    *)
    Definition get_unchecked (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ _ as I ], [ self; index ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let index := M.alloc (| index |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::slice::index::SliceIndex",
              I,
              [ Ty.apply (Ty.path "slice") [] [ T ] ],
              "get_unchecked",
              []
            |),
            [ M.read (| index |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_get_unchecked :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "get_unchecked" (get_unchecked T).
    
    (*
        pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
        where
            I: SliceIndex<Self>,
        {
            // SAFETY: the caller must uphold the safety requirements 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 *index.get_unchecked_mut(self) }
        }
    *)
    Definition get_unchecked_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ _ as I ], [ self; index ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let index := M.alloc (| index |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::slice::index::SliceIndex",
              I,
              [ Ty.apply (Ty.path "slice") [] [ T ] ],
              "get_unchecked_mut",
              []
            |),
            [ M.read (| index |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_get_unchecked_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "get_unchecked_mut" (get_unchecked_mut T).
    
    (*
        pub const fn as_ptr(&self) -> *const T {
            self as *const [T] as *const T
        }
    *)
    Definition as_ptr (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      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 :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_ptr" (as_ptr T).
    
    (*
        pub const fn as_mut_ptr(&mut self) -> *mut T {
            self as *mut [T] as *mut T
        }
    *)
    Definition as_mut_ptr (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      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 :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_mut_ptr" (as_mut_ptr T).
    
    (*
        pub const fn as_ptr_range(&self) -> Range<*const T> {
            let start = self.as_ptr();
            // SAFETY: The `add` here is safe, because:
            //
            //   - Both pointers are part of the same object, as pointing directly
            //     past the object also counts.
            //
            //   - The size of the slice is never larger than `isize::MAX` bytes, as
            //     noted here:
            //       - https://github.com/rust-lang/unsafe-code-guidelines/issues/102#issuecomment-473340447
            //       - https://doc.rust-lang.org/reference/behavior-considered-undefined.html
            //       - https://doc.rust-lang.org/core/slice/fn.from_raw_parts.html#safety
            //     (This doesn't seem normative yet, but the very same assumption is
            //     made in many places, including the Index implementation of slices.)
            //
            //   - There is no wrapping around involved, as slices do not wrap past
            //     the end of the address space.
            //
            // See the documentation of [`pointer::add`].
            let end = unsafe { start.add(self.len()) };
            start..end
        }
    *)
    Definition as_ptr_range (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ start :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "as_ptr", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ end_ :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.apply (Ty.path "*const") [] [ T ], "add", [] |),
                  [
                    M.read (| start |);
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |)
                  ]
                |)
              |) in
            M.alloc (|
              Value.StructRecord
                "core::ops::range::Range"
                [ ("start", M.read (| start |)); ("end_", M.read (| end_ |)) ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_ptr_range :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_ptr_range" (as_ptr_range T).
    
    (*
        pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> {
            let start = self.as_mut_ptr();
            // SAFETY: See as_ptr_range() above for why `add` here is safe.
            let end = unsafe { start.add(self.len()) };
            start..end
        }
    *)
    Definition as_mut_ptr_range
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ start :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "as_mut_ptr",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ end_ :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.apply (Ty.path "*mut") [] [ T ], "add", [] |),
                  [
                    M.read (| start |);
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |)
                  ]
                |)
              |) in
            M.alloc (|
              Value.StructRecord
                "core::ops::range::Range"
                [ ("start", M.read (| start |)); ("end_", M.read (| end_ |)) ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_mut_ptr_range :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_mut_ptr_range" (as_mut_ptr_range T).
    
    (*
        pub const fn swap(&mut self, a: usize, b: usize) {
            // FIXME: use swap_unchecked here (https://github.com/rust-lang/rust/pull/88540#issuecomment-944344343)
            // Can't take two mutable loans from one vector, so instead use raw pointers.
            let pa = &raw mut self[a];
            let pb = &raw mut self[b];
            // SAFETY: `pa` and `pb` have been created from safe mutable references and refer
            // to elements in the slice and therefore are guaranteed to be valid and aligned.
            // Note that accessing the elements behind `a` and `b` is checked and will
            // panic when out of bounds.
            unsafe {
                ptr::swap(pa, pb);
            }
        }
    *)
    Definition swap (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; a; b ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let a := M.alloc (| a |) in
          let b := M.alloc (| b |) in
          M.read (|
            let~ pa := M.alloc (| M.SubPointer.get_array_field (| M.read (| self |), a |) |) in
            let~ pb := M.alloc (| M.SubPointer.get_array_field (| M.read (| self |), b |) |) in
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::ptr::swap", [ T ] |),
                  [ M.read (| pa |); M.read (| pb |) ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "swap" (swap T).
    
    (*
        pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) {
            assert_unsafe_precondition!(
                check_library_ub,
                "slice::swap_unchecked requires that the indices are within the slice",
                (
                    len: usize = self.len(),
                    a: usize = a,
                    b: usize = b,
                ) => a < len && b < len,
            );
    
            let ptr = self.as_mut_ptr();
            // SAFETY: caller has to guarantee that `a < self.len()` and `b < self.len()`
            unsafe {
                ptr::swap(ptr.add(a), ptr.add(b));
            }
        }
    *)
    Definition swap_unchecked
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; a; b ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let a := M.alloc (| a |) in
          let b := M.alloc (| b |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::intrinsics::ub_checks", [] |),
                              []
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Self,
                              "precondition_check.swap_unchecked",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "len",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |);
                              M.read (| a |);
                              M.read (| b |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ ptr :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "as_mut_ptr",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::ptr::swap", [ T ] |),
                  [
                    M.call_closure (|
                      M.get_associated_function (| Ty.apply (Ty.path "*mut") [] [ T ], "add", [] |),
                      [ M.read (| ptr |); M.read (| a |) ]
                    |);
                    M.call_closure (|
                      M.get_associated_function (| Ty.apply (Ty.path "*mut") [] [ T ], "add", [] |),
                      [ M.read (| ptr |); M.read (| b |) ]
                    |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_unchecked :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "swap_unchecked" (swap_unchecked T).
    
    (*
        pub fn reverse(&mut self) {
            let half_len = self.len() / 2;
            let Range { start, end } = self.as_mut_ptr_range();
    
            // These slices will skip the middle item for an odd length,
            // since that one doesn't need to move.
            let (front_half, back_half) =
                // SAFETY: Both are subparts of the original slice, so the memory
                // range is valid, and they don't overlap because they're each only
                // half (or less) of the original slice.
                unsafe {
                    (
                        slice::from_raw_parts_mut(start, half_len),
                        slice::from_raw_parts_mut(end.sub(half_len), half_len),
                    )
                };
    
            // Introducing a function boundary here means that the two halves
            // get `noalias` markers, allowing better optimization as LLVM
            // knows that they're disjoint, unlike in the original slice.
            revswap(front_half, back_half, half_len);
    
            #[inline]
            fn revswap<T>(a: &mut [T], b: &mut [T], n: usize) {
                debug_assert!(a.len() == n);
                debug_assert!(b.len() == n);
    
                // Because this function is first compiled in isolation,
                // this check tells LLVM that the indexing below is
                // in-bounds. Then after inlining -- once the actual
                // lengths of the slices are known -- it's removed.
                let (a, b) = (&mut a[..n], &mut b[..n]);
    
                let mut i = 0;
                while i < n {
                    mem::swap(&mut a[i], &mut b[n - 1 - i]);
                    i += 1;
                }
            }
        }
    *)
    Definition reverse (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ half_len :=
              M.alloc (|
                BinOp.Wrap.div (|
                  M.call_closure (|
                    M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "len", [] |),
                    [ M.read (| self |) ]
                  |),
                  Value.Integer IntegerKind.Usize 2
                |)
              |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "as_mut_ptr_range",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_record_field (|
                        γ,
                        "core::ops::range::Range",
                        "start"
                      |) in
                    let γ0_1 :=
                      M.SubPointer.get_struct_record_field (|
                        γ,
                        "core::ops::range::Range",
                        "end"
                      |) in
                    let start := M.copy (| γ0_0 |) in
                    let end_ := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        Value.Tuple
                          [
                            M.call_closure (|
                              M.get_function (| "core::slice::raw::from_raw_parts_mut", [ T ] |),
                              [ M.read (| start |); M.read (| half_len |) ]
                            |);
                            M.call_closure (|
                              M.get_function (| "core::slice::raw::from_raw_parts_mut", [ T ] |),
                              [
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "*mut") [] [ T ],
                                    "sub",
                                    []
                                  |),
                                  [ M.read (| end_ |); M.read (| half_len |) ]
                                |);
                                M.read (| half_len |)
                              ]
                            |)
                          ]
                      |),
                      [
                        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 front_half := M.copy (| γ0_0 |) in
                            let back_half := M.copy (| γ0_1 |) in
                            let~ _ :=
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Self, "revswap.reverse", [] |),
                                  [
                                    M.read (| front_half |);
                                    M.read (| back_half |);
                                    M.read (| half_len |)
                                  ]
                                |)
                              |) in
                            M.alloc (| Value.Tuple [] |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "reverse" (reverse T).
    
    (*
        pub fn iter(&self) -> Iter<'_, T> {
            Iter::new(self)
        }
    *)
    Definition iter (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::Iter") [] [ T ],
              "new",
              []
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_iter :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "iter" (iter T).
    
    (*
        pub fn iter_mut(&mut self) -> IterMut<'_, T> {
            IterMut::new(self)
        }
    *)
    Definition iter_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::IterMut") [] [ T ],
              "new",
              []
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_iter_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "iter_mut" (iter_mut T).
    
    (*
        pub fn windows(&self, size: usize) -> Windows<'_, T> {
            let size = NonZero::new(size).expect("window size must be non-zero");
            Windows::new(self, size)
        }
    *)
    Definition windows (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; size ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let size := M.alloc (| size |) in
          M.read (|
            let~ size :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply
                      (Ty.path "core::option::Option")
                      []
                      [ Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ] ],
                    "expect",
                    []
                  |),
                  [
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ],
                        "new",
                        []
                      |),
                      [ M.read (| size |) ]
                    |);
                    M.read (| Value.String "window size must be non-zero" |)
                  ]
                |)
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::Windows") [] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |); M.read (| size |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_windows :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "windows" (windows T).
    
    (*
        pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
            assert!(chunk_size != 0, "chunk size must be non-zero");
            Chunks::new(self, chunk_size)
        }
    *)
    Definition chunks (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; chunk_size ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let chunk_size := M.alloc (| chunk_size |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| chunk_size |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::Chunks") [] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |); M.read (| chunk_size |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_chunks :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "chunks" (chunks T).
    
    (*
        pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
            assert!(chunk_size != 0, "chunk size must be non-zero");
            ChunksMut::new(self, chunk_size)
        }
    *)
    Definition chunks_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; chunk_size ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let chunk_size := M.alloc (| chunk_size |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| chunk_size |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::ChunksMut") [] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |); M.read (| chunk_size |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_chunks_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "chunks_mut" (chunks_mut T).
    
    (*
        pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
            assert!(chunk_size != 0, "chunk size must be non-zero");
            ChunksExact::new(self, chunk_size)
        }
    *)
    Definition chunks_exact (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; chunk_size ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let chunk_size := M.alloc (| chunk_size |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| chunk_size |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::ChunksExact") [] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |); M.read (| chunk_size |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_chunks_exact :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "chunks_exact" (chunks_exact T).
    
    (*
        pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
            assert!(chunk_size != 0, "chunk size must be non-zero");
            ChunksExactMut::new(self, chunk_size)
        }
    *)
    Definition chunks_exact_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; chunk_size ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let chunk_size := M.alloc (| chunk_size |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| chunk_size |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::ChunksExactMut") [] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |); M.read (| chunk_size |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_chunks_exact_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "chunks_exact_mut" (chunks_exact_mut T).
    
    (*
        pub const unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]] {
            assert_unsafe_precondition!(
                check_language_ub,
                "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",
                (n: usize = N, len: usize = self.len()) => n != 0 && len % n == 0,
            );
            // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
            let new_len = unsafe { exact_div(self.len(), N) };
            // SAFETY: We cast a slice of `new_len * N` elements into
            // a slice of `new_len` many `N` elements chunks.
            unsafe { from_raw_parts(self.as_ptr().cast(), new_len) }
        }
    *)
    Definition as_chunks_unchecked
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::ub_checks::check_language_ub", [] |),
                              []
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Self,
                              "precondition_check.as_chunks_unchecked",
                              []
                            |),
                            [
                              M.read (|
                                M.get_constant (| "core::slice::as_chunks_unchecked::N" |)
                              |);
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "len",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ new_len :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::exact_div", [ Ty.path "usize" ] |),
                  [
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |);
                    M.read (| M.get_constant (| "core::slice::as_chunks_unchecked::N" |) |)
                  ]
                |)
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::slice::raw::from_raw_parts",
                  [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "*const") [] [ T ],
                      "cast",
                      [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                    |),
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ T ],
                          "as_ptr",
                          []
                        |),
                        [ M.read (| self |) ]
                      |)
                    ]
                  |);
                  M.read (| new_len |)
                ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_chunks_unchecked :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_chunks_unchecked" (as_chunks_unchecked T).
    
    (*
        pub const fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T]) {
            assert!(N != 0, "chunk size must be non-zero");
            let len_rounded_down = self.len() / N * N;
            // SAFETY: The rounded-down value is always the same or smaller than the
            // original length, and thus must be in-bounds of the slice.
            let (multiple_of_n, remainder) = unsafe { self.split_at_unchecked(len_rounded_down) };
            // SAFETY: We already panicked for zero, and ensured by construction
            // that the length of the subslice is a multiple of N.
            let array_slice = unsafe { multiple_of_n.as_chunks_unchecked() };
            (array_slice, remainder)
        }
    *)
    Definition as_chunks (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| M.get_constant (| "core::slice::as_chunks::N" |) |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ len_rounded_down :=
              M.alloc (|
                BinOp.Wrap.mul (|
                  BinOp.Wrap.div (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |),
                    M.read (| M.get_constant (| "core::slice::as_chunks::N" |) |)
                  |),
                  M.read (| M.get_constant (| "core::slice::as_chunks::N" |) |)
                |)
              |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "split_at_unchecked",
                    []
                  |),
                  [ M.read (| self |); M.read (| len_rounded_down |) ]
                |)
              |),
              [
                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 multiple_of_n := M.copy (| γ0_0 |) in
                    let remainder := M.copy (| γ0_1 |) in
                    let~ array_slice :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "as_chunks_unchecked",
                            []
                          |),
                          [ M.read (| multiple_of_n |) ]
                        |)
                      |) in
                    M.alloc (| Value.Tuple [ M.read (| array_slice |); M.read (| remainder |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_chunks :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_chunks" (as_chunks T).
    
    (*
        pub const fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]]) {
            assert!(N != 0, "chunk size must be non-zero");
            let len = self.len() / N;
            let (remainder, multiple_of_n) = self.split_at(self.len() - len * N);
            // SAFETY: We already panicked for zero, and ensured by construction
            // that the length of the subslice is a multiple of N.
            let array_slice = unsafe { multiple_of_n.as_chunks_unchecked() };
            (remainder, array_slice)
        }
    *)
    Definition as_rchunks (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| M.get_constant (| "core::slice::as_rchunks::N" |) |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ len :=
              M.alloc (|
                BinOp.Wrap.div (|
                  M.call_closure (|
                    M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "len", [] |),
                    [ M.read (| self |) ]
                  |),
                  M.read (| M.get_constant (| "core::slice::as_rchunks::N" |) |)
                |)
              |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "split_at",
                    []
                  |),
                  [
                    M.read (| self |);
                    BinOp.Wrap.sub (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ T ],
                          "len",
                          []
                        |),
                        [ M.read (| self |) ]
                      |),
                      BinOp.Wrap.mul (|
                        M.read (| len |),
                        M.read (| M.get_constant (| "core::slice::as_rchunks::N" |) |)
                      |)
                    |)
                  ]
                |)
              |),
              [
                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 remainder := M.copy (| γ0_0 |) in
                    let multiple_of_n := M.copy (| γ0_1 |) in
                    let~ array_slice :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "as_chunks_unchecked",
                            []
                          |),
                          [ M.read (| multiple_of_n |) ]
                        |)
                      |) in
                    M.alloc (| Value.Tuple [ M.read (| remainder |); M.read (| array_slice |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_rchunks :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_rchunks" (as_rchunks T).
    
    (*
        pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N> {
            assert!(N != 0, "chunk size must be non-zero");
            ArrayChunks::new(self)
        }
    *)
    Definition array_chunks (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| M.get_constant (| "core::slice::array_chunks::N" |) |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::ArrayChunks") [ N ] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_array_chunks :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "array_chunks" (array_chunks T).
    
    (*
        pub const unsafe fn as_chunks_unchecked_mut<const N: usize>(&mut self) -> &mut [[T; N]] {
            assert_unsafe_precondition!(
                check_language_ub,
                "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",
                (n: usize = N, len: usize = self.len()) => n != 0 && len % n == 0
            );
            // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
            let new_len = unsafe { exact_div(self.len(), N) };
            // SAFETY: We cast a slice of `new_len * N` elements into
            // a slice of `new_len` many `N` elements chunks.
            unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), new_len) }
        }
    *)
    Definition as_chunks_unchecked_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::ub_checks::check_language_ub", [] |),
                              []
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Self,
                              "precondition_check.as_chunks_unchecked_mut",
                              []
                            |),
                            [
                              M.read (|
                                M.get_constant (| "core::slice::as_chunks_unchecked_mut::N" |)
                              |);
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "len",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ new_len :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::exact_div", [ Ty.path "usize" ] |),
                  [
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |);
                    M.read (| M.get_constant (| "core::slice::as_chunks_unchecked_mut::N" |) |)
                  ]
                |)
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::slice::raw::from_raw_parts_mut",
                  [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "*mut") [] [ T ],
                      "cast",
                      [ Ty.apply (Ty.path "array") [ N ] [ T ] ]
                    |),
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ T ],
                          "as_mut_ptr",
                          []
                        |),
                        [ M.read (| self |) ]
                      |)
                    ]
                  |);
                  M.read (| new_len |)
                ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_chunks_unchecked_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_chunks_unchecked_mut" (as_chunks_unchecked_mut T).
    
    (*
        pub const fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T]) {
            assert!(N != 0, "chunk size must be non-zero");
            let len_rounded_down = self.len() / N * N;
            // SAFETY: The rounded-down value is always the same or smaller than the
            // original length, and thus must be in-bounds of the slice.
            let (multiple_of_n, remainder) = unsafe { self.split_at_mut_unchecked(len_rounded_down) };
            // SAFETY: We already panicked for zero, and ensured by construction
            // that the length of the subslice is a multiple of N.
            let array_slice = unsafe { multiple_of_n.as_chunks_unchecked_mut() };
            (array_slice, remainder)
        }
    *)
    Definition as_chunks_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| M.get_constant (| "core::slice::as_chunks_mut::N" |) |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ len_rounded_down :=
              M.alloc (|
                BinOp.Wrap.mul (|
                  BinOp.Wrap.div (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |),
                    M.read (| M.get_constant (| "core::slice::as_chunks_mut::N" |) |)
                  |),
                  M.read (| M.get_constant (| "core::slice::as_chunks_mut::N" |) |)
                |)
              |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "split_at_mut_unchecked",
                    []
                  |),
                  [ M.read (| self |); M.read (| len_rounded_down |) ]
                |)
              |),
              [
                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 multiple_of_n := M.copy (| γ0_0 |) in
                    let remainder := M.copy (| γ0_1 |) in
                    let~ array_slice :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "as_chunks_unchecked_mut",
                            []
                          |),
                          [ M.read (| multiple_of_n |) ]
                        |)
                      |) in
                    M.alloc (| Value.Tuple [ M.read (| array_slice |); M.read (| remainder |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_chunks_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_chunks_mut" (as_chunks_mut T).
    
    (*
        pub const fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]]) {
            assert!(N != 0, "chunk size must be non-zero");
            let len = self.len() / N;
            let (remainder, multiple_of_n) = self.split_at_mut(self.len() - len * N);
            // SAFETY: We already panicked for zero, and ensured by construction
            // that the length of the subslice is a multiple of N.
            let array_slice = unsafe { multiple_of_n.as_chunks_unchecked_mut() };
            (remainder, array_slice)
        }
    *)
    Definition as_rchunks_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| M.get_constant (| "core::slice::as_rchunks_mut::N" |) |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ len :=
              M.alloc (|
                BinOp.Wrap.div (|
                  M.call_closure (|
                    M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "len", [] |),
                    [ M.read (| self |) ]
                  |),
                  M.read (| M.get_constant (| "core::slice::as_rchunks_mut::N" |) |)
                |)
              |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "split_at_mut",
                    []
                  |),
                  [
                    M.read (| self |);
                    BinOp.Wrap.sub (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ T ],
                          "len",
                          []
                        |),
                        [ M.read (| self |) ]
                      |),
                      BinOp.Wrap.mul (|
                        M.read (| len |),
                        M.read (| M.get_constant (| "core::slice::as_rchunks_mut::N" |) |)
                      |)
                    |)
                  ]
                |)
              |),
              [
                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 remainder := M.copy (| γ0_0 |) in
                    let multiple_of_n := M.copy (| γ0_1 |) in
                    let~ array_slice :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "as_chunks_unchecked_mut",
                            []
                          |),
                          [ M.read (| multiple_of_n |) ]
                        |)
                      |) in
                    M.alloc (| Value.Tuple [ M.read (| remainder |); M.read (| array_slice |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_rchunks_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_rchunks_mut" (as_rchunks_mut T).
    
    (*
        pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N> {
            assert!(N != 0, "chunk size must be non-zero");
            ArrayChunksMut::new(self)
        }
    *)
    Definition array_chunks_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (|
                                  M.get_constant (| "core::slice::array_chunks_mut::N" |)
                                |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::ArrayChunksMut") [ N ] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_array_chunks_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "array_chunks_mut" (array_chunks_mut T).
    
    (*
        pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
            assert!(N != 0, "window size must be non-zero");
            ArrayWindows::new(self)
        }
    *)
    Definition array_windows (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| M.get_constant (| "core::slice::array_windows::N" |) |),
                                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.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 "window size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::ArrayWindows") [ N ] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_array_windows :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "array_windows" (array_windows T).
    
    (*
        pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
            assert!(chunk_size != 0, "chunk size must be non-zero");
            RChunks::new(self, chunk_size)
        }
    *)
    Definition rchunks (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; chunk_size ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let chunk_size := M.alloc (| chunk_size |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| chunk_size |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::RChunks") [] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |); M.read (| chunk_size |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rchunks :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rchunks" (rchunks T).
    
    (*
        pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
            assert!(chunk_size != 0, "chunk size must be non-zero");
            RChunksMut::new(self, chunk_size)
        }
    *)
    Definition rchunks_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; chunk_size ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let chunk_size := M.alloc (| chunk_size |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| chunk_size |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::RChunksMut") [] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |); M.read (| chunk_size |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rchunks_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rchunks_mut" (rchunks_mut T).
    
    (*
        pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
            assert!(chunk_size != 0, "chunk size must be non-zero");
            RChunksExact::new(self, chunk_size)
        }
    *)
    Definition rchunks_exact (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; chunk_size ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let chunk_size := M.alloc (| chunk_size |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| chunk_size |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::RChunksExact") [] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |); M.read (| chunk_size |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rchunks_exact :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rchunks_exact" (rchunks_exact T).
    
    (*
        pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
            assert!(chunk_size != 0, "chunk size must be non-zero");
            RChunksExactMut::new(self, chunk_size)
        }
    *)
    Definition rchunks_exact_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; chunk_size ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let chunk_size := M.alloc (| chunk_size |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ne (|
                                M.read (| chunk_size |),
                                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.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 "chunk size must be non-zero" |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::slice::iter::RChunksExactMut") [] [ T ],
                  "new",
                  []
                |),
                [ M.read (| self |); M.read (| chunk_size |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rchunks_exact_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rchunks_exact_mut" (rchunks_exact_mut T).
    
    (*
        pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
        where
            F: FnMut(&T, &T) -> bool,
        {
            ChunkBy::new(self, pred)
        }
    *)
    Definition chunk_by (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::ChunkBy") [] [ T; F ],
              "new",
              []
            |),
            [ M.read (| self |); M.read (| pred |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_chunk_by :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "chunk_by" (chunk_by T).
    
    (*
        pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
        where
            F: FnMut(&T, &T) -> bool,
        {
            ChunkByMut::new(self, pred)
        }
    *)
    Definition chunk_by_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::ChunkByMut") [] [ T; F ],
              "new",
              []
            |),
            [ M.read (| self |); M.read (| pred |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_chunk_by_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "chunk_by_mut" (chunk_by_mut T).
    
    (*
        pub const fn split_at(&self, mid: usize) -> (&[T], &[T]) {
            match self.split_at_checked(mid) {
                Some(pair) => pair,
                None => panic!("mid > len"),
            }
        }
    *)
    Definition split_at (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      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.apply (Ty.path "slice") [] [ T ],
                    "split_at_checked",
                    []
                  |),
                  [ M.read (| self |); 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_));
                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::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 "mid > len" |) ] |)
                              ]
                            |)
                          ]
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_at :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_at" (split_at T).
    
    (*
        pub const fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
            match self.split_at_mut_checked(mid) {
                Some(pair) => pair,
                None => panic!("mid > len"),
            }
        }
    *)
    Definition split_at_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      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.apply (Ty.path "slice") [] [ T ],
                    "split_at_mut_checked",
                    []
                  |),
                  [ M.read (| self |); 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_));
                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::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 "mid > len" |) ] |)
                              ]
                            |)
                          ]
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_at_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_at_mut" (split_at_mut T).
    
    (*
        pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
            // FIXME(const-hack): the const function `from_raw_parts` is used to make this
            // function const; previously the implementation used
            // `(self.get_unchecked(..mid), self.get_unchecked(mid..))`
    
            let len = self.len();
            let ptr = self.as_ptr();
    
            assert_unsafe_precondition!(
                check_library_ub,
                "slice::split_at_unchecked requires the index to be within the slice",
                (mid: usize = mid, len: usize = len) => mid <= len,
            );
    
            // SAFETY: Caller has to check that `0 <= mid <= self.len()`
            unsafe { (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), unchecked_sub(len, mid))) }
        }
    *)
    Definition split_at_unchecked
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      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.apply (Ty.path "slice") [] [ T ], "len", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ ptr :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "as_ptr", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::intrinsics::ub_checks", [] |),
                              []
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Self,
                              "precondition_check.split_at_unchecked",
                              []
                            |),
                            [ M.read (| mid |); M.read (| len |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.call_closure (|
                    M.get_function (| "core::slice::raw::from_raw_parts", [ T ] |),
                    [ M.read (| ptr |); M.read (| mid |) ]
                  |);
                  M.call_closure (|
                    M.get_function (| "core::slice::raw::from_raw_parts", [ T ] |),
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "*const") [] [ T ],
                          "add",
                          []
                        |),
                        [ M.read (| ptr |); M.read (| mid |) ]
                      |);
                      M.call_closure (|
                        M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "usize" ] |),
                        [ M.read (| len |); M.read (| mid |) ]
                      |)
                    ]
                  |)
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_at_unchecked :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_at_unchecked" (split_at_unchecked T).
    
    (*
        pub const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
            let len = self.len();
            let ptr = self.as_mut_ptr();
    
            assert_unsafe_precondition!(
                check_library_ub,
                "slice::split_at_mut_unchecked requires the index to be within the slice",
                (mid: usize = mid, len: usize = len) => mid <= len,
            );
    
            // SAFETY: Caller has to check that `0 <= mid <= self.len()`.
            //
            // `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
            // is fine.
            unsafe {
                (
                    from_raw_parts_mut(ptr, mid),
                    from_raw_parts_mut(ptr.add(mid), unchecked_sub(len, mid)),
                )
            }
        }
    *)
    Definition split_at_mut_unchecked
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      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.apply (Ty.path "slice") [] [ T ], "len", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ ptr :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "as_mut_ptr",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::intrinsics::ub_checks", [] |),
                              []
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Self,
                              "precondition_check.split_at_mut_unchecked",
                              []
                            |),
                            [ M.read (| mid |); M.read (| len |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.call_closure (|
                    M.get_function (| "core::slice::raw::from_raw_parts_mut", [ T ] |),
                    [ M.read (| ptr |); M.read (| mid |) ]
                  |);
                  M.call_closure (|
                    M.get_function (| "core::slice::raw::from_raw_parts_mut", [ T ] |),
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "*mut") [] [ T ],
                          "add",
                          []
                        |),
                        [ M.read (| ptr |); M.read (| mid |) ]
                      |);
                      M.call_closure (|
                        M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "usize" ] |),
                        [ M.read (| len |); M.read (| mid |) ]
                      |)
                    ]
                  |)
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_at_mut_unchecked :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_at_mut_unchecked" (split_at_mut_unchecked T).
    
    (*
        pub const fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])> {
            if mid <= self.len() {
                // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
                // fulfills the requirements of `split_at_unchecked`.
                Some(unsafe { self.split_at_unchecked(mid) })
            } else {
                None
            }
        }
    *)
    Definition split_at_checked
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      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 (|
                          BinOp.le (|
                            M.read (| mid |),
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "len",
                                []
                              |),
                              [ M.read (| self |) ]
                            |)
                          |)
                        |)) 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.apply (Ty.path "slice") [] [ T ],
                              "split_at_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_checked :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_at_checked" (split_at_checked T).
    
    (*
        pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut [T], &mut [T])> {
            if mid <= self.len() {
                // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
                // fulfills the requirements of `split_at_unchecked`.
                Some(unsafe { self.split_at_mut_unchecked(mid) })
            } else {
                None
            }
        }
    *)
    Definition split_at_mut_checked
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      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 (|
                          BinOp.le (|
                            M.read (| mid |),
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "len",
                                []
                              |),
                              [ M.read (| self |) ]
                            |)
                          |)
                        |)) 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.apply (Ty.path "slice") [] [ T ],
                              "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 :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_at_mut_checked" (split_at_mut_checked T).
    
    (*
        pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
        where
            F: FnMut(&T) -> bool,
        {
            Split::new(self, pred)
        }
    *)
    Definition split (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::Split") [] [ T; F ],
              "new",
              []
            |),
            [ M.read (| self |); M.read (| pred |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split" (split T).
    
    (*
        pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
        where
            F: FnMut(&T) -> bool,
        {
            SplitMut::new(self, pred)
        }
    *)
    Definition split_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::SplitMut") [] [ T; F ],
              "new",
              []
            |),
            [ M.read (| self |); M.read (| pred |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_mut" (split_mut T).
    
    (*
        pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
        where
            F: FnMut(&T) -> bool,
        {
            SplitInclusive::new(self, pred)
        }
    *)
    Definition split_inclusive
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::SplitInclusive") [] [ T; F ],
              "new",
              []
            |),
            [ M.read (| self |); M.read (| pred |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_inclusive :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_inclusive" (split_inclusive T).
    
    (*
        pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
        where
            F: FnMut(&T) -> bool,
        {
            SplitInclusiveMut::new(self, pred)
        }
    *)
    Definition split_inclusive_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::SplitInclusiveMut") [] [ T; F ],
              "new",
              []
            |),
            [ M.read (| self |); M.read (| pred |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_inclusive_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_inclusive_mut" (split_inclusive_mut T).
    
    (*
        pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
        where
            F: FnMut(&T) -> bool,
        {
            RSplit::new(self, pred)
        }
    *)
    Definition rsplit (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::RSplit") [] [ T; F ],
              "new",
              []
            |),
            [ M.read (| self |); M.read (| pred |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rsplit :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rsplit" (rsplit T).
    
    (*
        pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
        where
            F: FnMut(&T) -> bool,
        {
            RSplitMut::new(self, pred)
        }
    *)
    Definition rsplit_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::RSplitMut") [] [ T; F ],
              "new",
              []
            |),
            [ M.read (| self |); M.read (| pred |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rsplit_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rsplit_mut" (rsplit_mut T).
    
    (*
        pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
        where
            F: FnMut(&T) -> bool,
        {
            SplitN::new(self.split(pred), n)
        }
    *)
    Definition splitn (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; n; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::SplitN") [] [ T; F ],
              "new",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "split", [ F ] |),
                [ M.read (| self |); M.read (| pred |) ]
              |);
              M.read (| n |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_splitn :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "splitn" (splitn T).
    
    (*
        pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
        where
            F: FnMut(&T) -> bool,
        {
            SplitNMut::new(self.split_mut(pred), n)
        }
    *)
    Definition splitn_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; n; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::SplitNMut") [] [ T; F ],
              "new",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ T ],
                  "split_mut",
                  [ F ]
                |),
                [ M.read (| self |); M.read (| pred |) ]
              |);
              M.read (| n |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_splitn_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "splitn_mut" (splitn_mut T).
    
    (*
        pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
        where
            F: FnMut(&T) -> bool,
        {
            RSplitN::new(self.rsplit(pred), n)
        }
    *)
    Definition rsplitn (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; n; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::RSplitN") [] [ T; F ],
              "new",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ T ],
                  "rsplit",
                  [ F ]
                |),
                [ M.read (| self |); M.read (| pred |) ]
              |);
              M.read (| n |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rsplitn :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rsplitn" (rsplitn T).
    
    (*
        pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
        where
            F: FnMut(&T) -> bool,
        {
            RSplitNMut::new(self.rsplit_mut(pred), n)
        }
    *)
    Definition rsplitn_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; n; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::slice::iter::RSplitNMut") [] [ T; F ],
              "new",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ T ],
                  "rsplit_mut",
                  [ F ]
                |),
                [ M.read (| self |); M.read (| pred |) ]
              |);
              M.read (| n |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rsplitn_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rsplitn_mut" (rsplitn_mut T).
    
    (*
        pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
        where
            F: FnMut(&T) -> bool,
        {
            let index = self.iter().position(pred)?;
            Some((&self[..index], &self[index + 1..]))
        }
    *)
    Definition split_once (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ index :=
                  M.copy (|
                    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.path "usize" ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::iterator::Iterator",
                                Ty.apply (Ty.path "core::slice::iter::Iter") [] [ T ],
                                [],
                                "position",
                                [ F ]
                              |),
                              [
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ T ],
                                      "iter",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |)
                                |);
                                M.read (| pred |)
                              ]
                            |)
                          ]
                        |)
                      |),
                      [
                        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.apply (Ty.path "slice") [] [ T ] ];
                                                Ty.apply
                                                  (Ty.path "&")
                                                  []
                                                  [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                              ]
                                          ],
                                        [
                                          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))
                      ]
                    |)
                  |) in
                M.alloc (|
                  Value.StructTuple
                    "core::option::Option::Some"
                    [
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::ops::index::Index",
                              Ty.apply (Ty.path "slice") [] [ T ],
                              [
                                Ty.apply
                                  (Ty.path "core::ops::range::RangeTo")
                                  []
                                  [ Ty.path "usize" ]
                              ],
                              "index",
                              []
                            |),
                            [
                              M.read (| self |);
                              Value.StructRecord
                                "core::ops::range::RangeTo"
                                [ ("end_", M.read (| index |)) ]
                            ]
                          |);
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::ops::index::Index",
                              Ty.apply (Ty.path "slice") [] [ T ],
                              [
                                Ty.apply
                                  (Ty.path "core::ops::range::RangeFrom")
                                  []
                                  [ Ty.path "usize" ]
                              ],
                              "index",
                              []
                            |),
                            [
                              M.read (| self |);
                              Value.StructRecord
                                "core::ops::range::RangeFrom"
                                [
                                  ("start",
                                    BinOp.Wrap.add (|
                                      M.read (| index |),
                                      Value.Integer IntegerKind.Usize 1
                                    |))
                                ]
                            ]
                          |)
                        ]
                    ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_split_once :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "split_once" (split_once T).
    
    (*
        pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
        where
            F: FnMut(&T) -> bool,
        {
            let index = self.iter().rposition(pred)?;
            Some((&self[..index], &self[index + 1..]))
        }
    *)
    Definition rsplit_once (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ index :=
                  M.copy (|
                    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.path "usize" ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::iterator::Iterator",
                                Ty.apply (Ty.path "core::slice::iter::Iter") [] [ T ],
                                [],
                                "rposition",
                                [ F ]
                              |),
                              [
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ T ],
                                      "iter",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |)
                                |);
                                M.read (| pred |)
                              ]
                            |)
                          ]
                        |)
                      |),
                      [
                        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.apply (Ty.path "slice") [] [ T ] ];
                                                Ty.apply
                                                  (Ty.path "&")
                                                  []
                                                  [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                              ]
                                          ],
                                        [
                                          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))
                      ]
                    |)
                  |) in
                M.alloc (|
                  Value.StructTuple
                    "core::option::Option::Some"
                    [
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::ops::index::Index",
                              Ty.apply (Ty.path "slice") [] [ T ],
                              [
                                Ty.apply
                                  (Ty.path "core::ops::range::RangeTo")
                                  []
                                  [ Ty.path "usize" ]
                              ],
                              "index",
                              []
                            |),
                            [
                              M.read (| self |);
                              Value.StructRecord
                                "core::ops::range::RangeTo"
                                [ ("end_", M.read (| index |)) ]
                            ]
                          |);
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::ops::index::Index",
                              Ty.apply (Ty.path "slice") [] [ T ],
                              [
                                Ty.apply
                                  (Ty.path "core::ops::range::RangeFrom")
                                  []
                                  [ Ty.path "usize" ]
                              ],
                              "index",
                              []
                            |),
                            [
                              M.read (| self |);
                              Value.StructRecord
                                "core::ops::range::RangeFrom"
                                [
                                  ("start",
                                    BinOp.Wrap.add (|
                                      M.read (| index |),
                                      Value.Integer IntegerKind.Usize 1
                                    |))
                                ]
                            ]
                          |)
                        ]
                    ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rsplit_once :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rsplit_once" (rsplit_once T).
    
    (*
        pub fn contains(&self, x: &T) -> bool
        where
            T: PartialEq,
        {
            cmp::SliceContains::slice_contains(x, self)
        }
    *)
    Definition contains (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; x ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_trait_method (| "core::slice::cmp::SliceContains", T, [], "slice_contains", [] |),
            [ M.read (| x |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_contains :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "contains" (contains T).
    
    (*
        pub fn starts_with(&self, needle: &[T]) -> bool
        where
            T: PartialEq,
        {
            let n = needle.len();
            self.len() >= n && needle == &self[..n]
        }
    *)
    Definition starts_with (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; needle ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let needle := M.alloc (| needle |) in
          M.read (|
            let~ n :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "len", [] |),
                  [ M.read (| needle |) ]
                |)
              |) in
            M.alloc (|
              LogicalOp.and (|
                BinOp.ge (|
                  M.call_closure (|
                    M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "len", [] |),
                    [ M.read (| self |) ]
                  |),
                  M.read (| n |)
                |),
                ltac:(M.monadic
                  (M.call_closure (|
                    M.get_trait_method (|
                      "core::cmp::PartialEq",
                      Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ T ] ],
                      [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ T ] ] ],
                      "eq",
                      []
                    |),
                    [
                      needle;
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::ops::index::Index",
                            Ty.apply (Ty.path "slice") [] [ T ],
                            [ Ty.apply (Ty.path "core::ops::range::RangeTo") [] [ Ty.path "usize" ]
                            ],
                            "index",
                            []
                          |),
                          [
                            M.read (| self |);
                            Value.StructRecord
                              "core::ops::range::RangeTo"
                              [ ("end_", M.read (| n |)) ]
                          ]
                        |)
                      |)
                    ]
                  |)))
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_starts_with :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "starts_with" (starts_with T).
    
    (*
        pub fn ends_with(&self, needle: &[T]) -> bool
        where
            T: PartialEq,
        {
            let (m, n) = (self.len(), needle.len());
            m >= n && needle == &self[m - n..]
        }
    *)
    Definition ends_with (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; needle ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let needle := M.alloc (| needle |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                Value.Tuple
                  [
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |);
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| needle |) ]
                    |)
                  ]
              |),
              [
                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 m := M.copy (| γ0_0 |) in
                    let n := M.copy (| γ0_1 |) in
                    M.alloc (|
                      LogicalOp.and (|
                        BinOp.ge (| M.read (| m |), M.read (| n |) |),
                        ltac:(M.monadic
                          (M.call_closure (|
                            M.get_trait_method (|
                              "core::cmp::PartialEq",
                              Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ T ] ],
                              [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ T ] ] ],
                              "eq",
                              []
                            |),
                            [
                              needle;
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::ops::index::Index",
                                    Ty.apply (Ty.path "slice") [] [ T ],
                                    [
                                      Ty.apply
                                        (Ty.path "core::ops::range::RangeFrom")
                                        []
                                        [ Ty.path "usize" ]
                                    ],
                                    "index",
                                    []
                                  |),
                                  [
                                    M.read (| self |);
                                    Value.StructRecord
                                      "core::ops::range::RangeFrom"
                                      [
                                        ("start",
                                          BinOp.Wrap.sub (| M.read (| m |), M.read (| n |) |))
                                      ]
                                  ]
                                |)
                              |)
                            ]
                          |)))
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ends_with :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "ends_with" (ends_with T).
    
    (*
        pub fn strip_prefix<P: SlicePattern<Item = T> + ?Sized>(&self, prefix: &P) -> Option<&[T]>
        where
            T: PartialEq,
        {
            // This function will need rewriting if and when SlicePattern becomes more sophisticated.
            let prefix = prefix.as_slice();
            let n = prefix.len();
            if n <= self.len() {
                let (head, tail) = self.split_at(n);
                if head == prefix {
                    return Some(tail);
                }
            }
            None
        }
    *)
    Definition strip_prefix (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ P ], [ self; prefix ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let prefix := M.alloc (| prefix |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ prefix :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (| "core::slice::SlicePattern", P, [], "as_slice", [] |),
                      [ M.read (| prefix |) ]
                    |)
                  |) in
                let~ n :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| prefix |) ]
                    |)
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.le (|
                                  M.read (| n |),
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ T ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.match_operator (|
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "split_at",
                                  []
                                |),
                                [ M.read (| self |); M.read (| n |) ]
                              |)
                            |),
                            [
                              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 head := M.copy (| γ0_0 |) in
                                  let tail := M.copy (| γ0_1 |) in
                                  M.match_operator (|
                                    M.alloc (| Value.Tuple [] |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ :=
                                            M.use
                                              (M.alloc (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::cmp::PartialEq",
                                                    Ty.apply
                                                      (Ty.path "&")
                                                      []
                                                      [ Ty.apply (Ty.path "slice") [] [ T ] ],
                                                    [
                                                      Ty.apply
                                                        (Ty.path "&")
                                                        []
                                                        [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                                    ],
                                                    "eq",
                                                    []
                                                  |),
                                                  [ head; prefix ]
                                                |)
                                              |)) 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.StructTuple
                                                    "core::option::Option::Some"
                                                    [ M.read (| tail |) ]
                                                |)
                                              |)
                                            |)
                                          |)));
                                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                    ]
                                  |)))
                            ]
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                M.alloc (| Value.StructTuple "core::option::Option::None" [] |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strip_prefix :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "strip_prefix" (strip_prefix T).
    
    (*
        pub fn strip_suffix<P: SlicePattern<Item = T> + ?Sized>(&self, suffix: &P) -> Option<&[T]>
        where
            T: PartialEq,
        {
            // This function will need rewriting if and when SlicePattern becomes more sophisticated.
            let suffix = suffix.as_slice();
            let (len, n) = (self.len(), suffix.len());
            if n <= len {
                let (head, tail) = self.split_at(len - n);
                if tail == suffix {
                    return Some(head);
                }
            }
            None
        }
    *)
    Definition strip_suffix (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ P ], [ self; suffix ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let suffix := M.alloc (| suffix |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ suffix :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (| "core::slice::SlicePattern", P, [], "as_slice", [] |),
                      [ M.read (| suffix |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (|
                    Value.Tuple
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "len",
                            []
                          |),
                          [ M.read (| self |) ]
                        |);
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "len",
                            []
                          |),
                          [ M.read (| suffix |) ]
                        |)
                      ]
                  |),
                  [
                    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 len := M.copy (| γ0_0 |) in
                        let n := M.copy (| γ0_1 |) in
                        let~ _ :=
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ :=
                                    M.use
                                      (M.alloc (|
                                        BinOp.le (| M.read (| n |), M.read (| len |) |)
                                      |)) in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  M.match_operator (|
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "slice") [] [ T ],
                                          "split_at",
                                          []
                                        |),
                                        [
                                          M.read (| self |);
                                          BinOp.Wrap.sub (| M.read (| len |), M.read (| n |) |)
                                        ]
                                      |)
                                    |),
                                    [
                                      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 head := M.copy (| γ0_0 |) in
                                          let tail := M.copy (| γ0_1 |) in
                                          M.match_operator (|
                                            M.alloc (| Value.Tuple [] |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ :=
                                                    M.use
                                                      (M.alloc (|
                                                        M.call_closure (|
                                                          M.get_trait_method (|
                                                            "core::cmp::PartialEq",
                                                            Ty.apply
                                                              (Ty.path "&")
                                                              []
                                                              [ Ty.apply (Ty.path "slice") [] [ T ]
                                                              ],
                                                            [
                                                              Ty.apply
                                                                (Ty.path "&")
                                                                []
                                                                [
                                                                  Ty.apply
                                                                    (Ty.path "slice")
                                                                    []
                                                                    [ T ]
                                                                ]
                                                            ],
                                                            "eq",
                                                            []
                                                          |),
                                                          [ tail; suffix ]
                                                        |)
                                                      |)) 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.StructTuple
                                                            "core::option::Option::Some"
                                                            [ M.read (| head |) ]
                                                        |)
                                                      |)
                                                    |)
                                                  |)));
                                              fun γ =>
                                                ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                            ]
                                          |)))
                                    ]
                                  |)));
                              fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strip_suffix :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "strip_suffix" (strip_suffix T).
    
    (*
        pub fn binary_search(&self, x: &T) -> Result<usize, usize>
        where
            T: Ord,
        {
            self.binary_search_by(|p| p.cmp(x))
        }
    *)
    Definition binary_search (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; x ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "slice") [] [ T ],
              "binary_search_by",
              [
                Ty.function
                  [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ] ] ]
                  (Ty.path "core::cmp::Ordering")
              ]
            |),
            [
              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 p := M.copy (| γ |) in
                                M.call_closure (|
                                  M.get_trait_method (| "core::cmp::Ord", T, [], "cmp", [] |),
                                  [ M.read (| p |); M.read (| x |) ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_binary_search :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "binary_search" (binary_search T).
    
    (*
        pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
        where
            F: FnMut(&'a T) -> Ordering,
        {
            let mut size = self.len();
            if size == 0 {
                return Err(0);
            }
            let mut base = 0usize;
    
            // This loop intentionally doesn't have an early exit if the comparison
            // returns Equal. We want the number of loop iterations to depend *only*
            // on the size of the input slice so that the CPU can reliably predict
            // the loop count.
            while size > 1 {
                let half = size / 2;
                let mid = base + half;
    
                // SAFETY: the call is made safe by the following inconstants:
                // - `mid >= 0`: by definition
                // - `mid < size`: `mid = size / 2 + size / 4 + size / 8 ...`
                let cmp = f(unsafe { self.get_unchecked(mid) });
    
                // Binary search interacts poorly with branch prediction, so force
                // the compiler to use conditional moves if supported by the target
                // architecture.
                base = select_unpredictable(cmp == Greater, base, mid);
    
                // This is imprecise in the case where `size` is odd and the
                // comparison returns Greater: the mid element still gets included
                // by `size` even though it's known to be larger than the element
                // being searched for.
                //
                // This is fine though: we gain more performance by keeping the
                // loop iteration count invariant (and thus predictable) than we
                // lose from considering one additional element.
                size -= half;
            }
    
            // SAFETY: base is always in [0, size) because base <= mid.
            let cmp = f(unsafe { self.get_unchecked(base) });
            if cmp == Equal {
                // SAFETY: same as the `get_unchecked` above.
                unsafe { hint::assert_unchecked(base < self.len()) };
                Ok(base)
            } else {
                let result = base + (cmp == Less) as usize;
                // SAFETY: same as the `get_unchecked` above.
                // Note that this is `<=`, unlike the assume in the `Ok` path.
                unsafe { hint::assert_unchecked(result <= self.len()) };
                Err(result)
            }
        }
    *)
    Definition binary_search_by
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let f := M.alloc (| f |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ size :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |)
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| size |), 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.StructTuple
                                    "core::result::Result::Err"
                                    [ Value.Integer IntegerKind.Usize 0 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
                let~ _ :=
                  M.loop (|
                    ltac:(M.monadic
                      (M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    BinOp.gt (|
                                      M.read (| size |),
                                      Value.Integer IntegerKind.Usize 1
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              let~ half :=
                                M.alloc (|
                                  BinOp.Wrap.div (|
                                    M.read (| size |),
                                    Value.Integer IntegerKind.Usize 2
                                  |)
                                |) in
                              let~ mid :=
                                M.alloc (|
                                  BinOp.Wrap.add (| M.read (| base |), M.read (| half |) |)
                                |) in
                              let~ cmp :=
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::function::FnMut",
                                      F,
                                      [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ] ] ],
                                      "call_mut",
                                      []
                                    |),
                                    [
                                      f;
                                      Value.Tuple
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ T ],
                                              "get_unchecked",
                                              [ Ty.path "usize" ]
                                            |),
                                            [ M.read (| self |); M.read (| mid |) ]
                                          |)
                                        ]
                                    ]
                                  |)
                                |) in
                              let~ _ :=
                                M.write (|
                                  base,
                                  M.call_closure (|
                                    M.get_function (|
                                      "core::intrinsics::select_unpredictable",
                                      [ Ty.path "usize" ]
                                    |),
                                    [
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::cmp::PartialEq",
                                          Ty.path "core::cmp::Ordering",
                                          [ Ty.path "core::cmp::Ordering" ],
                                          "eq",
                                          []
                                        |),
                                        [
                                          cmp;
                                          M.alloc (|
                                            Value.StructTuple "core::cmp::Ordering::Greater" []
                                          |)
                                        ]
                                      |);
                                      M.read (| base |);
                                      M.read (| mid |)
                                    ]
                                  |)
                                |) in
                              let~ _ :=
                                let β := size in
                                M.write (|
                                  β,
                                  BinOp.Wrap.sub (| M.read (| β |), M.read (| half |) |)
                                |) in
                              M.alloc (| Value.Tuple [] |)));
                          fun γ =>
                            ltac:(M.monadic
                              (M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    let~ _ :=
                                      M.alloc (|
                                        M.never_to_any (| M.read (| M.break (||) |) |)
                                      |) in
                                    M.alloc (| Value.Tuple [] |)
                                  |)
                                |)
                              |)))
                        ]
                      |)))
                  |) in
                let~ cmp :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::ops::function::FnMut",
                        F,
                        [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ] ] ],
                        "call_mut",
                        []
                      |),
                      [
                        f;
                        Value.Tuple
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "get_unchecked",
                                [ Ty.path "usize" ]
                              |),
                              [ M.read (| self |); M.read (| base |) ]
                            |)
                          ]
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::cmp::PartialEq",
                                  Ty.path "core::cmp::Ordering",
                                  [ Ty.path "core::cmp::Ordering" ],
                                  "eq",
                                  []
                                |),
                                [
                                  cmp;
                                  M.alloc (| Value.StructTuple "core::cmp::Ordering::Equal" [] |)
                                ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        let~ _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::hint::assert_unchecked", [] |),
                              [
                                BinOp.lt (|
                                  M.read (| base |),
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ T ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |)
                                |)
                              ]
                            |)
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| base |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let~ result :=
                          M.alloc (|
                            BinOp.Wrap.add (|
                              M.read (| base |),
                              M.rust_cast
                                (M.call_closure (|
                                  M.get_trait_method (|
                                    "core::cmp::PartialEq",
                                    Ty.path "core::cmp::Ordering",
                                    [ Ty.path "core::cmp::Ordering" ],
                                    "eq",
                                    []
                                  |),
                                  [
                                    cmp;
                                    M.alloc (| Value.StructTuple "core::cmp::Ordering::Less" [] |)
                                  ]
                                |))
                            |)
                          |) in
                        let~ _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::hint::assert_unchecked", [] |),
                              [
                                BinOp.le (|
                                  M.read (| result |),
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ T ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |)
                                |)
                              ]
                            |)
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Err" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_binary_search_by :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "binary_search_by" (binary_search_by T).
    
    (*
        pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
        where
            F: FnMut(&'a T) -> B,
            B: Ord,
        {
            self.binary_search_by(|k| f(k).cmp(b))
        }
    *)
    Definition binary_search_by_key
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ B; F ], [ self; b; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let b := M.alloc (| b |) in
          let f := M.alloc (| f |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "slice") [] [ T ],
              "binary_search_by",
              [
                Ty.function
                  [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ] ] ]
                  (Ty.path "core::cmp::Ordering")
              ]
            |),
            [
              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 k := M.copy (| γ |) in
                                M.call_closure (|
                                  M.get_trait_method (| "core::cmp::Ord", B, [], "cmp", [] |),
                                  [
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::ops::function::FnMut",
                                          F,
                                          [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ] ] ],
                                          "call_mut",
                                          []
                                        |),
                                        [ f; Value.Tuple [ M.read (| k |) ] ]
                                      |)
                                    |);
                                    M.read (| b |)
                                  ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_binary_search_by_key :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "binary_search_by_key" (binary_search_by_key T).
    
    (*
        pub fn sort_unstable(&mut self)
        where
            T: Ord,
        {
            sort::unstable::sort(self, &mut T::lt);
        }
    *)
    Definition sort_unstable (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (|
                    "core::slice::sort::unstable::sort",
                    [
                      T;
                      Ty.function
                        [ Ty.apply (Ty.path "&") [] [ T ]; Ty.apply (Ty.path "&") [] [ T ] ]
                        (Ty.path "bool")
                    ]
                  |),
                  [
                    M.read (| self |);
                    M.alloc (|
                      M.get_trait_method (| "core::cmp::PartialOrd", T, [ T ], "lt", [] |)
                    |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_sort_unstable :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "sort_unstable" (sort_unstable T).
    
    (*
        pub fn sort_unstable_by<F>(&mut self, mut compare: F)
        where
            F: FnMut(&T, &T) -> Ordering,
        {
            sort::unstable::sort(self, &mut |a, b| compare(a, b) == Ordering::Less);
        }
    *)
    Definition sort_unstable_by
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; compare ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let compare := M.alloc (| compare |) in
          M.read (|
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (|
                    "core::slice::sort::unstable::sort",
                    [
                      T;
                      Ty.function
                        [
                          Ty.tuple
                            [ Ty.apply (Ty.path "&") [] [ T ]; Ty.apply (Ty.path "&") [] [ T ] ]
                        ]
                        (Ty.path "bool")
                    ]
                  |),
                  [
                    M.read (| self |);
                    M.alloc (|
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0; α1 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let a := M.copy (| γ |) in
                                        M.match_operator (|
                                          M.alloc (| α1 |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let b := M.copy (| γ |) in
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::cmp::PartialEq",
                                                    Ty.path "core::cmp::Ordering",
                                                    [ Ty.path "core::cmp::Ordering" ],
                                                    "eq",
                                                    []
                                                  |),
                                                  [
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_trait_method (|
                                                          "core::ops::function::FnMut",
                                                          F,
                                                          [
                                                            Ty.tuple
                                                              [
                                                                Ty.apply (Ty.path "&") [] [ T ];
                                                                Ty.apply (Ty.path "&") [] [ T ]
                                                              ]
                                                          ],
                                                          "call_mut",
                                                          []
                                                        |),
                                                        [
                                                          compare;
                                                          Value.Tuple
                                                            [ M.read (| a |); M.read (| b |) ]
                                                        ]
                                                      |)
                                                    |);
                                                    M.alloc (|
                                                      Value.StructTuple
                                                        "core::cmp::Ordering::Less"
                                                        []
                                                    |)
                                                  ]
                                                |)))
                                          ]
                                        |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_sort_unstable_by :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "sort_unstable_by" (sort_unstable_by T).
    
    (*
        pub fn sort_unstable_by_key<K, F>(&mut self, mut f: F)
        where
            F: FnMut(&T) -> K,
            K: Ord,
        {
            sort::unstable::sort(self, &mut |a, b| f(a).lt(&f(b)));
        }
    *)
    Definition sort_unstable_by_key
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ K; F ], [ self; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let f := M.alloc (| f |) in
          M.read (|
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (|
                    "core::slice::sort::unstable::sort",
                    [
                      T;
                      Ty.function
                        [
                          Ty.tuple
                            [ Ty.apply (Ty.path "&") [] [ T ]; Ty.apply (Ty.path "&") [] [ T ] ]
                        ]
                        (Ty.path "bool")
                    ]
                  |),
                  [
                    M.read (| self |);
                    M.alloc (|
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0; α1 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let a := M.copy (| γ |) in
                                        M.match_operator (|
                                          M.alloc (| α1 |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let b := M.copy (| γ |) in
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::cmp::PartialOrd",
                                                    K,
                                                    [ K ],
                                                    "lt",
                                                    []
                                                  |),
                                                  [
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_trait_method (|
                                                          "core::ops::function::FnMut",
                                                          F,
                                                          [
                                                            Ty.tuple
                                                              [ Ty.apply (Ty.path "&") [] [ T ] ]
                                                          ],
                                                          "call_mut",
                                                          []
                                                        |),
                                                        [ f; Value.Tuple [ M.read (| a |) ] ]
                                                      |)
                                                    |);
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_trait_method (|
                                                          "core::ops::function::FnMut",
                                                          F,
                                                          [
                                                            Ty.tuple
                                                              [ Ty.apply (Ty.path "&") [] [ T ] ]
                                                          ],
                                                          "call_mut",
                                                          []
                                                        |),
                                                        [ f; Value.Tuple [ M.read (| b |) ] ]
                                                      |)
                                                    |)
                                                  ]
                                                |)))
                                          ]
                                        |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_sort_unstable_by_key :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "sort_unstable_by_key" (sort_unstable_by_key T).
    
    (*
        pub fn select_nth_unstable(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T])
        where
            T: Ord,
        {
            sort::select::partition_at_index(self, index, T::lt)
        }
    *)
    Definition select_nth_unstable
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; index ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let index := M.alloc (| index |) in
          M.call_closure (|
            M.get_function (|
              "core::slice::sort::select::partition_at_index",
              [
                T;
                Ty.function
                  [ Ty.apply (Ty.path "&") [] [ T ]; Ty.apply (Ty.path "&") [] [ T ] ]
                  (Ty.path "bool")
              ]
            |),
            [
              M.read (| self |);
              M.read (| index |);
              M.get_trait_method (| "core::cmp::PartialOrd", T, [ T ], "lt", [] |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_select_nth_unstable :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "select_nth_unstable" (select_nth_unstable T).
    
    (*
        pub fn select_nth_unstable_by<F>(
            &mut self,
            index: usize,
            mut compare: F,
        ) -> (&mut [T], &mut T, &mut [T])
        where
            F: FnMut(&T, &T) -> Ordering,
        {
            sort::select::partition_at_index(self, index, |a: &T, b: &T| compare(a, b) == Less)
        }
    *)
    Definition select_nth_unstable_by
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; index; compare ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let index := M.alloc (| index |) in
          let compare := M.alloc (| compare |) in
          M.call_closure (|
            M.get_function (|
              "core::slice::sort::select::partition_at_index",
              [
                T;
                Ty.function
                  [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ]; Ty.apply (Ty.path "&") [] [ T ] ] ]
                  (Ty.path "bool")
              ]
            |),
            [
              M.read (| self |);
              M.read (| index |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0; α1 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let a := M.copy (| γ |) in
                                M.match_operator (|
                                  M.alloc (| α1 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let b := M.copy (| γ |) in
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::cmp::PartialEq",
                                            Ty.path "core::cmp::Ordering",
                                            [ Ty.path "core::cmp::Ordering" ],
                                            "eq",
                                            []
                                          |),
                                          [
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::function::FnMut",
                                                  F,
                                                  [
                                                    Ty.tuple
                                                      [
                                                        Ty.apply (Ty.path "&") [] [ T ];
                                                        Ty.apply (Ty.path "&") [] [ T ]
                                                      ]
                                                  ],
                                                  "call_mut",
                                                  []
                                                |),
                                                [
                                                  compare;
                                                  Value.Tuple [ M.read (| a |); M.read (| b |) ]
                                                ]
                                              |)
                                            |);
                                            M.alloc (|
                                              Value.StructTuple "core::cmp::Ordering::Less" []
                                            |)
                                          ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_select_nth_unstable_by :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "select_nth_unstable_by" (select_nth_unstable_by T).
    
    (*
        pub fn select_nth_unstable_by_key<K, F>(
            &mut self,
            index: usize,
            mut f: F,
        ) -> (&mut [T], &mut T, &mut [T])
        where
            F: FnMut(&T) -> K,
            K: Ord,
        {
            sort::select::partition_at_index(self, index, |a: &T, b: &T| f(a).lt(&f(b)))
        }
    *)
    Definition select_nth_unstable_by_key
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ K; F ], [ self; index; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let index := M.alloc (| index |) in
          let f := M.alloc (| f |) in
          M.call_closure (|
            M.get_function (|
              "core::slice::sort::select::partition_at_index",
              [
                T;
                Ty.function
                  [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ]; Ty.apply (Ty.path "&") [] [ T ] ] ]
                  (Ty.path "bool")
              ]
            |),
            [
              M.read (| self |);
              M.read (| index |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0; α1 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let a := M.copy (| γ |) in
                                M.match_operator (|
                                  M.alloc (| α1 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let b := M.copy (| γ |) in
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::cmp::PartialOrd",
                                            K,
                                            [ K ],
                                            "lt",
                                            []
                                          |),
                                          [
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::function::FnMut",
                                                  F,
                                                  [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ] ] ],
                                                  "call_mut",
                                                  []
                                                |),
                                                [ f; Value.Tuple [ M.read (| a |) ] ]
                                              |)
                                            |);
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::function::FnMut",
                                                  F,
                                                  [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ] ] ],
                                                  "call_mut",
                                                  []
                                                |),
                                                [ f; Value.Tuple [ M.read (| b |) ] ]
                                              |)
                                            |)
                                          ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_select_nth_unstable_by_key :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "select_nth_unstable_by_key" (select_nth_unstable_by_key T).
    
    (*
        pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
        where
            T: PartialEq,
        {
            self.partition_dedup_by(|a, b| a == b)
        }
    *)
    Definition partition_dedup
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "slice") [] [ T ],
              "partition_dedup_by",
              [
                Ty.function
                  [
                    Ty.tuple
                      [ Ty.apply (Ty.path "&mut") [] [ T ]; Ty.apply (Ty.path "&mut") [] [ T ] ]
                  ]
                  (Ty.path "bool")
              ]
            |),
            [
              M.read (| self |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0; α1 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let a := M.copy (| γ |) in
                                M.match_operator (|
                                  M.alloc (| α1 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let b := M.copy (| γ |) in
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::cmp::PartialEq",
                                            Ty.apply (Ty.path "&mut") [] [ T ],
                                            [ Ty.apply (Ty.path "&mut") [] [ T ] ],
                                            "eq",
                                            []
                                          |),
                                          [ a; b ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_partition_dedup :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "partition_dedup" (partition_dedup T).
    
    (*
        pub fn partition_dedup_by<F>(&mut self, mut same_bucket: F) -> (&mut [T], &mut [T])
        where
            F: FnMut(&mut T, &mut T) -> bool,
        {
            // Although we have a mutable reference to `self`, we cannot make
            // *arbitrary* changes. The `same_bucket` calls could panic, so we
            // must ensure that the slice is in a valid state at all times.
            //
            // The way that we handle this is by using swaps; we iterate
            // over all the elements, swapping as we go so that at the end
            // the elements we wish to keep are in the front, and those we
            // wish to reject are at the back. We can then split the slice.
            // This operation is still `O(n)`.
            //
            // Example: We start in this state, where `r` represents "next
            // read" and `w` represents "next_write".
            //
            //           r
            //     +---+---+---+---+---+---+
            //     | 0 | 1 | 1 | 2 | 3 | 3 |
            //     +---+---+---+---+---+---+
            //           w
            //
            // Comparing self[r] against self[w-1], this is not a duplicate, so
            // we swap self[r] and self[w] (no effect as r==w) and then increment both
            // r and w, leaving us with:
            //
            //               r
            //     +---+---+---+---+---+---+
            //     | 0 | 1 | 1 | 2 | 3 | 3 |
            //     +---+---+---+---+---+---+
            //               w
            //
            // Comparing self[r] against self[w-1], this value is a duplicate,
            // so we increment `r` but leave everything else unchanged:
            //
            //                   r
            //     +---+---+---+---+---+---+
            //     | 0 | 1 | 1 | 2 | 3 | 3 |
            //     +---+---+---+---+---+---+
            //               w
            //
            // Comparing self[r] against self[w-1], this is not a duplicate,
            // so swap self[r] and self[w] and advance r and w:
            //
            //                       r
            //     +---+---+---+---+---+---+
            //     | 0 | 1 | 2 | 1 | 3 | 3 |
            //     +---+---+---+---+---+---+
            //                   w
            //
            // Not a duplicate, repeat:
            //
            //                           r
            //     +---+---+---+---+---+---+
            //     | 0 | 1 | 2 | 3 | 1 | 3 |
            //     +---+---+---+---+---+---+
            //                       w
            //
            // Duplicate, advance r. End of slice. Split at w.
    
            let len = self.len();
            if len <= 1 {
                return (self, &mut []);
            }
    
            let ptr = self.as_mut_ptr();
            let mut next_read: usize = 1;
            let mut next_write: usize = 1;
    
            // SAFETY: the `while` condition guarantees `next_read` and `next_write`
            // are less than `len`, thus are inside `self`. `prev_ptr_write` points to
            // one element before `ptr_write`, but `next_write` starts at 1, so
            // `prev_ptr_write` is never less than 0 and is inside the slice.
            // This fulfils the requirements for dereferencing `ptr_read`, `prev_ptr_write`
            // and `ptr_write`, and for using `ptr.add(next_read)`, `ptr.add(next_write - 1)`
            // and `prev_ptr_write.offset(1)`.
            //
            // `next_write` is also incremented at most once per loop at most meaning
            // no element is skipped when it may need to be swapped.
            //
            // `ptr_read` and `prev_ptr_write` never point to the same element. This
            // is required for `&mut *ptr_read`, `&mut *prev_ptr_write` to be safe.
            // The explanation is simply that `next_read >= next_write` is always true,
            // thus `next_read > next_write - 1` is too.
            unsafe {
                // Avoid bounds checks by using raw pointers.
                while next_read < len {
                    let ptr_read = ptr.add(next_read);
                    let prev_ptr_write = ptr.add(next_write - 1);
                    if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) {
                        if next_read != next_write {
                            let ptr_write = prev_ptr_write.add(1);
                            mem::swap(&mut *ptr_read, &mut *ptr_write);
                        }
                        next_write += 1;
                    }
                    next_read += 1;
                }
            }
    
            self.split_at_mut(next_write)
        }
    *)
    Definition partition_dedup_by
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; same_bucket ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let same_bucket := M.alloc (| same_bucket |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ len :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |)
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.le (| M.read (| len |), Value.Integer IntegerKind.Usize 1 |)
                              |)) 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.Tuple [ M.read (| self |); M.alloc (| Value.Array [] |) ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ ptr :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "as_mut_ptr",
                        []
                      |),
                      [ M.read (| self |) ]
                    |)
                  |) in
                let~ next_read := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
                let~ next_write := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
                let~ _ :=
                  M.loop (|
                    ltac:(M.monadic
                      (M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    BinOp.lt (| M.read (| next_read |), M.read (| len |) |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              let~ ptr_read :=
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "*mut") [] [ T ],
                                      "add",
                                      []
                                    |),
                                    [ M.read (| ptr |); M.read (| next_read |) ]
                                  |)
                                |) in
                              let~ prev_ptr_write :=
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "*mut") [] [ T ],
                                      "add",
                                      []
                                    |),
                                    [
                                      M.read (| ptr |);
                                      BinOp.Wrap.sub (|
                                        M.read (| next_write |),
                                        Value.Integer IntegerKind.Usize 1
                                      |)
                                    ]
                                  |)
                                |) in
                              let~ _ :=
                                M.match_operator (|
                                  M.alloc (| Value.Tuple [] |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ :=
                                          M.use
                                            (M.alloc (|
                                              UnOp.not (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::ops::function::FnMut",
                                                    F,
                                                    [
                                                      Ty.tuple
                                                        [
                                                          Ty.apply (Ty.path "&mut") [] [ T ];
                                                          Ty.apply (Ty.path "&mut") [] [ T ]
                                                        ]
                                                    ],
                                                    "call_mut",
                                                    []
                                                  |),
                                                  [
                                                    same_bucket;
                                                    Value.Tuple
                                                      [
                                                        M.read (| ptr_read |);
                                                        M.read (| prev_ptr_write |)
                                                      ]
                                                  ]
                                                |)
                                              |)
                                            |)) in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        let~ _ :=
                                          M.match_operator (|
                                            M.alloc (| Value.Tuple [] |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ :=
                                                    M.use
                                                      (M.alloc (|
                                                        BinOp.ne (|
                                                          M.read (| next_read |),
                                                          M.read (| next_write |)
                                                        |)
                                                      |)) in
                                                  let _ :=
                                                    M.is_constant_or_break_match (|
                                                      M.read (| γ |),
                                                      Value.Bool true
                                                    |) in
                                                  let~ ptr_write :=
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.apply (Ty.path "*mut") [] [ T ],
                                                          "add",
                                                          []
                                                        |),
                                                        [
                                                          M.read (| prev_ptr_write |);
                                                          Value.Integer IntegerKind.Usize 1
                                                        ]
                                                      |)
                                                    |) in
                                                  let~ _ :=
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_function (|
                                                          "core::mem::swap",
                                                          [ T ]
                                                        |),
                                                        [
                                                          M.read (| ptr_read |);
                                                          M.read (| ptr_write |)
                                                        ]
                                                      |)
                                                    |) in
                                                  M.alloc (| Value.Tuple [] |)));
                                              fun γ =>
                                                ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                            ]
                                          |) in
                                        let~ _ :=
                                          let β := next_write in
                                          M.write (|
                                            β,
                                            BinOp.Wrap.add (|
                                              M.read (| β |),
                                              Value.Integer IntegerKind.Usize 1
                                            |)
                                          |) in
                                        M.alloc (| Value.Tuple [] |)));
                                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                  ]
                                |) in
                              let~ _ :=
                                let β := next_read in
                                M.write (|
                                  β,
                                  BinOp.Wrap.add (|
                                    M.read (| β |),
                                    Value.Integer IntegerKind.Usize 1
                                  |)
                                |) in
                              M.alloc (| Value.Tuple [] |)));
                          fun γ =>
                            ltac:(M.monadic
                              (M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    let~ _ :=
                                      M.alloc (|
                                        M.never_to_any (| M.read (| M.break (||) |) |)
                                      |) in
                                    M.alloc (| Value.Tuple [] |)
                                  |)
                                |)
                              |)))
                        ]
                      |)))
                  |) in
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "slice") [] [ T ],
                      "split_at_mut",
                      []
                    |),
                    [ M.read (| self |); M.read (| next_write |) ]
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_partition_dedup_by :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "partition_dedup_by" (partition_dedup_by T).
    
    (*
        pub fn partition_dedup_by_key<K, F>(&mut self, mut key: F) -> (&mut [T], &mut [T])
        where
            F: FnMut(&mut T) -> K,
            K: PartialEq,
        {
            self.partition_dedup_by(|a, b| key(a) == key(b))
        }
    *)
    Definition partition_dedup_by_key
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ K; F ], [ self; key ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let key := M.alloc (| key |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "slice") [] [ T ],
              "partition_dedup_by",
              [
                Ty.function
                  [
                    Ty.tuple
                      [ Ty.apply (Ty.path "&mut") [] [ T ]; Ty.apply (Ty.path "&mut") [] [ T ] ]
                  ]
                  (Ty.path "bool")
              ]
            |),
            [
              M.read (| self |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0; α1 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let a := M.copy (| γ |) in
                                M.match_operator (|
                                  M.alloc (| α1 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let b := M.copy (| γ |) in
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::cmp::PartialEq",
                                            K,
                                            [ K ],
                                            "eq",
                                            []
                                          |),
                                          [
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::function::FnMut",
                                                  F,
                                                  [ Ty.tuple [ Ty.apply (Ty.path "&mut") [] [ T ] ]
                                                  ],
                                                  "call_mut",
                                                  []
                                                |),
                                                [ key; Value.Tuple [ M.read (| a |) ] ]
                                              |)
                                            |);
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::function::FnMut",
                                                  F,
                                                  [ Ty.tuple [ Ty.apply (Ty.path "&mut") [] [ T ] ]
                                                  ],
                                                  "call_mut",
                                                  []
                                                |),
                                                [ key; Value.Tuple [ M.read (| b |) ] ]
                                              |)
                                            |)
                                          ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_partition_dedup_by_key :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "partition_dedup_by_key" (partition_dedup_by_key T).
    
    (*
        pub fn rotate_left(&mut self, mid: usize) {
            assert!(mid <= self.len());
            let k = self.len() - mid;
            let p = self.as_mut_ptr();
    
            // SAFETY: The range `[p.add(mid) - mid, p.add(mid) + k)` is trivially
            // valid for reading and writing, as required by `ptr_rotate`.
            unsafe {
                rotate::ptr_rotate(mid, p.add(mid), k);
            }
        }
    *)
    Definition rotate_left (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; mid ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let mid := M.alloc (| mid |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.le (|
                                M.read (| mid |),
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ T ],
                                    "len",
                                    []
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |)
                            |)
                          |)) 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", [] |),
                            [ M.read (| Value.String "assertion failed: mid <= self.len()" |) ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ k :=
              M.alloc (|
                BinOp.Wrap.sub (|
                  M.call_closure (|
                    M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "len", [] |),
                    [ M.read (| self |) ]
                  |),
                  M.read (| mid |)
                |)
              |) in
            let~ p :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "as_mut_ptr",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::slice::rotate::ptr_rotate", [ T ] |),
                  [
                    M.read (| mid |);
                    M.call_closure (|
                      M.get_associated_function (| Ty.apply (Ty.path "*mut") [] [ T ], "add", [] |),
                      [ M.read (| p |); M.read (| mid |) ]
                    |);
                    M.read (| k |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rotate_left" (rotate_left T).
    
    (*
        pub fn rotate_right(&mut self, k: usize) {
            assert!(k <= self.len());
            let mid = self.len() - k;
            let p = self.as_mut_ptr();
    
            // SAFETY: The range `[p.add(mid) - mid, p.add(mid) + k)` is trivially
            // valid for reading and writing, as required by `ptr_rotate`.
            unsafe {
                rotate::ptr_rotate(mid, p.add(mid), k);
            }
        }
    *)
    Definition rotate_right (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; k ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let k := M.alloc (| k |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.le (|
                                M.read (| k |),
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ T ],
                                    "len",
                                    []
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |)
                            |)
                          |)) 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", [] |),
                            [ M.read (| Value.String "assertion failed: k <= self.len()" |) ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ mid :=
              M.alloc (|
                BinOp.Wrap.sub (|
                  M.call_closure (|
                    M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "len", [] |),
                    [ M.read (| self |) ]
                  |),
                  M.read (| k |)
                |)
              |) in
            let~ p :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "as_mut_ptr",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::slice::rotate::ptr_rotate", [ T ] |),
                  [
                    M.read (| mid |);
                    M.call_closure (|
                      M.get_associated_function (| Ty.apply (Ty.path "*mut") [] [ T ], "add", [] |),
                      [ M.read (| p |); M.read (| mid |) ]
                    |);
                    M.read (| k |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "rotate_right" (rotate_right T).
    
    (*
        pub fn fill(&mut self, value: T)
        where
            T: Clone,
        {
            specialize::SpecFill::spec_fill(self, value);
        }
    *)
    Definition fill (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; value ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let value := M.alloc (| value |) in
          M.read (|
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "core::slice::specialize::SpecFill",
                    Ty.apply (Ty.path "slice") [] [ T ],
                    [ T ],
                    "spec_fill",
                    []
                  |),
                  [ M.read (| self |); M.read (| value |) ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_fill :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "fill" (fill T).
    
    (*
        pub fn fill_with<F>(&mut self, mut f: F)
        where
            F: FnMut() -> T,
        {
            for el in self {
                *el = f();
            }
        }
    *)
    Definition fill_with (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let f := M.alloc (| f |) in
          M.read (|
            M.use
              (M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::iter::traits::collect::IntoIterator",
                      Ty.apply (Ty.path "&mut") [] [ Ty.apply (Ty.path "slice") [] [ T ] ],
                      [],
                      "into_iter",
                      []
                    |),
                    [ M.read (| self |) ]
                  |)
                |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let iter := M.copy (| γ |) in
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::iter::traits::iterator::Iterator",
                                    Ty.apply (Ty.path "core::slice::iter::IterMut") [] [ T ],
                                    [],
                                    "next",
                                    []
                                  |),
                                  [ iter ]
                                |)
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let _ :=
                                      M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                    M.alloc (| M.never_to_any (| M.read (| M.break (||) |) |) |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::option::Option::Some",
                                        0
                                      |) in
                                    let el := M.copy (| γ0_0 |) in
                                    let~ _ :=
                                      M.write (|
                                        M.read (| el |),
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::ops::function::FnMut",
                                            F,
                                            [ Ty.tuple [] ],
                                            "call_mut",
                                            []
                                          |),
                                          [ f; Value.Tuple [] ]
                                        |)
                                      |) in
                                    M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)))
                ]
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_fill_with :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "fill_with" (fill_with T).
    
    (*
        pub fn clone_from_slice(&mut self, src: &[T])
        where
            T: Clone,
        {
            self.spec_clone_from(src);
        }
    *)
    Definition clone_from_slice
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; src ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let src := M.alloc (| src |) in
          M.read (|
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "core::slice::CloneFromSpec",
                    Ty.apply (Ty.path "slice") [] [ T ],
                    [ T ],
                    "spec_clone_from",
                    []
                  |),
                  [ M.read (| self |); M.read (| src |) ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_clone_from_slice :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "clone_from_slice" (clone_from_slice T).
    
    (*
        pub fn copy_from_slice(&mut self, src: &[T])
        where
            T: Copy,
        {
            // The panic code path was put into a cold function to not bloat the
            // call site.
            #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
            #[cfg_attr(feature = "panic_immediate_abort", inline)]
            #[track_caller]
            fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! {
                panic!(
                    "source slice length ({}) does not match destination slice length ({})",
                    src_len, dst_len,
                );
            }
    
            if self.len() != src.len() {
                len_mismatch_fail(self.len(), src.len());
            }
    
            // SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
            // checked to have the same length. The slices cannot overlap because
            // mutable references are exclusive.
            unsafe {
                ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len());
            }
        }
    *)
    Definition copy_from_slice
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; src ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let src := M.alloc (| src |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            BinOp.ne (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "len",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |),
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "len",
                                  []
                                |),
                                [ M.read (| src |) ]
                              |)
                            |)
                          |)) 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_associated_function (|
                              Self,
                              "len_mismatch_fail.copy_from_slice",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "len",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |);
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "slice") [] [ T ],
                                  "len",
                                  []
                                |),
                                [ M.read (| src |) ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::copy_nonoverlapping", [ T ] |),
                  [
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "as_ptr",
                        []
                      |),
                      [ M.read (| src |) ]
                    |);
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "as_mut_ptr",
                        []
                      |),
                      [ M.read (| self |) ]
                    |);
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_copy_from_slice :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "copy_from_slice" (copy_from_slice T).
    
    (*
        pub fn copy_within<R: RangeBounds<usize>>(&mut self, src: R, dest: usize)
        where
            T: Copy,
        {
            let Range { start: src_start, end: src_end } = slice::range(src, ..self.len());
            let count = src_end - src_start;
            assert!(dest <= self.len() - count, "dest is out of bounds");
            // SAFETY: the conditions for `ptr::copy` have all been checked above,
            // as have those for `ptr::add`.
            unsafe {
                // Derive both `src_ptr` and `dest_ptr` from the same loan
                let ptr = self.as_mut_ptr();
                let src_ptr = ptr.add(src_start);
                let dest_ptr = ptr.add(dest);
                ptr::copy(src_ptr, dest_ptr, count);
            }
        }
    *)
    Definition copy_within (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ R ], [ self; src; dest ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let src := M.alloc (| src |) in
          let dest := M.alloc (| dest |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::slice::index::range", [ R ] |),
                  [
                    M.read (| src |);
                    Value.StructRecord
                      "core::ops::range::RangeTo"
                      [
                        ("end_",
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "slice") [] [ T ],
                              "len",
                              []
                            |),
                            [ M.read (| self |) ]
                          |))
                      ]
                  ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_record_field (|
                        γ,
                        "core::ops::range::Range",
                        "start"
                      |) in
                    let γ0_1 :=
                      M.SubPointer.get_struct_record_field (|
                        γ,
                        "core::ops::range::Range",
                        "end"
                      |) in
                    let src_start := M.copy (| γ0_0 |) in
                    let src_end := M.copy (| γ0_1 |) in
                    let~ count :=
                      M.alloc (|
                        BinOp.Wrap.sub (| M.read (| src_end |), M.read (| src_start |) |)
                      |) in
                    let~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    UnOp.not (|
                                      BinOp.le (|
                                        M.read (| dest |),
                                        BinOp.Wrap.sub (|
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ T ],
                                              "len",
                                              []
                                            |),
                                            [ M.read (| self |) ]
                                          |),
                                          M.read (| count |)
                                        |)
                                      |)
                                    |)
                                  |)) 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_const",
                                          []
                                        |),
                                        [
                                          M.alloc (|
                                            Value.Array
                                              [ M.read (| Value.String "dest is out of bounds" |) ]
                                          |)
                                        ]
                                      |)
                                    ]
                                  |)
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    let~ ptr :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "as_mut_ptr",
                            []
                          |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let~ src_ptr :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "*mut") [] [ T ],
                            "add",
                            []
                          |),
                          [ M.read (| ptr |); M.read (| src_start |) ]
                        |)
                      |) in
                    let~ dest_ptr :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "*mut") [] [ T ],
                            "add",
                            []
                          |),
                          [ M.read (| ptr |); M.read (| dest |) ]
                        |)
                      |) in
                    let~ _ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_function (| "core::intrinsics::copy", [ T ] |),
                          [
                            (* MutToConstPointer *) M.pointer_coercion (M.read (| src_ptr |));
                            M.read (| dest_ptr |);
                            M.read (| count |)
                          ]
                        |)
                      |) in
                    M.alloc (| Value.Tuple [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_copy_within :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "copy_within" (copy_within T).
    
    (*
        pub fn swap_with_slice(&mut self, other: &mut [T]) {
            assert!(self.len() == other.len(), "destination and source slices have different lengths");
            // SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
            // checked to have the same length. The slices cannot overlap because
            // mutable references are exclusive.
            unsafe {
                ptr::swap_nonoverlapping(self.as_mut_ptr(), other.as_mut_ptr(), self.len());
            }
        }
    *)
    Definition swap_with_slice
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.eq (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ T ],
                                    "len",
                                    []
                                  |),
                                  [ M.read (| self |) ]
                                |),
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ T ],
                                    "len",
                                    []
                                  |),
                                  [ M.read (| other |) ]
                                |)
                              |)
                            |)
                          |)) 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_const",
                                  []
                                |),
                                [
                                  M.alloc (|
                                    Value.Array
                                      [
                                        M.read (|
                                          Value.String
                                            "destination and source slices have different lengths"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::ptr::swap_nonoverlapping", [ T ] |),
                  [
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "as_mut_ptr",
                        []
                      |),
                      [ M.read (| self |) ]
                    |);
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "as_mut_ptr",
                        []
                      |),
                      [ M.read (| other |) ]
                    |);
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_with_slice :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "swap_with_slice" (swap_with_slice T).
    
    (*
        fn align_to_offsets<U>(&self) -> (usize, usize) {
            // What we gonna do about `rest` is figure out what multiple of `U`s we can put in a
            // lowest number of `T`s. And how many `T`s we need for each such "multiple".
            //
            // Consider for example T=u8 U=u16. Then we can put 1 U in 2 Ts. Simple. Now, consider
            // for example a case where size_of::<T> = 16, size_of::<U> = 24. We can put 2 Us in
            // place of every 3 Ts in the `rest` slice. A bit more complicated.
            //
            // Formula to calculate this is:
            //
            // Us = lcm(size_of::<T>, size_of::<U>) / size_of::<U>
            // Ts = lcm(size_of::<T>, size_of::<U>) / size_of::<T>
            //
            // Expanded and simplified:
            //
            // Us = size_of::<T> / gcd(size_of::<T>, size_of::<U>)
            // Ts = size_of::<U> / gcd(size_of::<T>, size_of::<U>)
            //
            // Luckily since all this is constant-evaluated... performance here matters not!
            const fn gcd(a: usize, b: usize) -> usize {
                if b == 0 { a } else { gcd(b, a % b) }
            }
    
            // Explicitly wrap the function call in a const block so it gets
            // constant-evaluated even in debug mode.
            let gcd: usize = const { gcd(mem::size_of::<T>(), mem::size_of::<U>()) };
            let ts: usize = mem::size_of::<U>() / gcd;
            let us: usize = mem::size_of::<T>() / gcd;
    
            // Armed with this knowledge, we can find how many `U`s we can fit!
            let us_len = self.len() / ts * us;
            // And how many `T`s will be in the trailing slice!
            let ts_len = self.len() % ts;
            (us_len, ts_len)
        }
    *)
    Definition align_to_offsets
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ U ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ gcd :=
              M.copy (| M.get_constant (| "core::slice::align_to_offsets_discriminant" |) |) in
            let~ ts :=
              M.alloc (|
                BinOp.Wrap.div (|
                  M.call_closure (| M.get_function (| "core::mem::size_of", [ U ] |), [] |),
                  M.read (| gcd |)
                |)
              |) in
            let~ us :=
              M.alloc (|
                BinOp.Wrap.div (|
                  M.call_closure (| M.get_function (| "core::mem::size_of", [ T ] |), [] |),
                  M.read (| gcd |)
                |)
              |) in
            let~ us_len :=
              M.alloc (|
                BinOp.Wrap.mul (|
                  BinOp.Wrap.div (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "len",
                        []
                      |),
                      [ M.read (| self |) ]
                    |),
                    M.read (| ts |)
                  |),
                  M.read (| us |)
                |)
              |) in
            let~ ts_len :=
              M.alloc (|
                BinOp.Wrap.rem (|
                  M.call_closure (|
                    M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "len", [] |),
                    [ M.read (| self |) ]
                  |),
                  M.read (| ts |)
                |)
              |) in
            M.alloc (| Value.Tuple [ M.read (| us_len |); M.read (| ts_len |) ] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_align_to_offsets :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "align_to_offsets" (align_to_offsets T).
    
    (*
        pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T]) {
            // Note that most of this function will be constant-evaluated,
            if U::IS_ZST || T::IS_ZST {
                // handle ZSTs specially, which is – don't handle them at all.
                return (self, &[], &[]);
            }
    
            // First, find at what point do we split between the first and 2nd slice. Easy with
            // ptr.align_offset.
            let ptr = self.as_ptr();
            // SAFETY: See the `align_to_mut` method for the detailed safety comment.
            let offset = unsafe { crate::ptr::align_offset(ptr, mem::align_of::<U>()) };
            if offset > self.len() {
                (self, &[], &[])
            } else {
                let (left, rest) = self.split_at(offset);
                let (us_len, ts_len) = rest.align_to_offsets::<U>();
                // Inform Miri that we want to consider the "middle" pointer to be suitably aligned.
                #[cfg(miri)]
                crate::intrinsics::miri_promise_symbolic_alignment(
                    rest.as_ptr().cast(),
                    mem::align_of::<U>(),
                );
                // SAFETY: now `rest` is definitely aligned, so `from_raw_parts` below is okay,
                // since the caller guarantees that we can transmute `T` to `U` safely.
                unsafe {
                    (
                        left,
                        from_raw_parts(rest.as_ptr() as *const U, us_len),
                        from_raw_parts(rest.as_ptr().add(rest.len() - ts_len), ts_len),
                    )
                }
            }
        }
    *)
    Definition align_to (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ U ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) 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 (|
                                LogicalOp.or (|
                                  M.read (|
                                    M.get_constant (| "core::mem::SizedTypeProperties::IS_ZST" |)
                                  |),
                                  ltac:(M.monadic
                                    (M.read (|
                                      M.get_constant (| "core::mem::SizedTypeProperties::IS_ZST" |)
                                    |)))
                                |)
                              |)) 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.Tuple
                                    [
                                      M.read (| self |);
                                      M.alloc (| Value.Array [] |);
                                      M.alloc (| Value.Array [] |)
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ ptr :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "as_ptr",
                        []
                      |),
                      [ M.read (| self |) ]
                    |)
                  |) in
                let~ offset :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::ptr::align_offset", [ T ] |),
                      [
                        M.read (| ptr |);
                        M.call_closure (| M.get_function (| "core::mem::align_of", [ U ] |), [] |)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.gt (|
                                M.read (| offset |),
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ T ],
                                    "len",
                                    []
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          Value.Tuple
                            [
                              M.read (| self |);
                              M.alloc (| Value.Array [] |);
                              M.alloc (| Value.Array [] |)
                            ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "split_at",
                                []
                              |),
                              [ M.read (| self |); M.read (| offset |) ]
                            |)
                          |),
                          [
                            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 left := M.copy (| γ0_0 |) in
                                let rest := M.copy (| γ0_1 |) in
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ T ],
                                        "align_to_offsets",
                                        [ U ]
                                      |),
                                      [ M.read (| rest |) ]
                                    |)
                                  |),
                                  [
                                    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 us_len := M.copy (| γ0_0 |) in
                                        let ts_len := M.copy (| γ0_1 |) in
                                        M.alloc (|
                                          Value.Tuple
                                            [
                                              M.read (| left |);
                                              M.call_closure (|
                                                M.get_function (|
                                                  "core::slice::raw::from_raw_parts",
                                                  [ U ]
                                                |),
                                                [
                                                  M.rust_cast
                                                    (M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.apply (Ty.path "slice") [] [ T ],
                                                        "as_ptr",
                                                        []
                                                      |),
                                                      [ M.read (| rest |) ]
                                                    |));
                                                  M.read (| us_len |)
                                                ]
                                              |);
                                              M.call_closure (|
                                                M.get_function (|
                                                  "core::slice::raw::from_raw_parts",
                                                  [ T ]
                                                |),
                                                [
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply (Ty.path "*const") [] [ T ],
                                                      "add",
                                                      []
                                                    |),
                                                    [
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.apply (Ty.path "slice") [] [ T ],
                                                          "as_ptr",
                                                          []
                                                        |),
                                                        [ M.read (| rest |) ]
                                                      |);
                                                      BinOp.Wrap.sub (|
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.apply (Ty.path "slice") [] [ T ],
                                                            "len",
                                                            []
                                                          |),
                                                          [ M.read (| rest |) ]
                                                        |),
                                                        M.read (| ts_len |)
                                                      |)
                                                    ]
                                                  |);
                                                  M.read (| ts_len |)
                                                ]
                                              |)
                                            ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_align_to :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "align_to" (align_to T).
    
    (*
        pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T]) {
            // Note that most of this function will be constant-evaluated,
            if U::IS_ZST || T::IS_ZST {
                // handle ZSTs specially, which is – don't handle them at all.
                return (self, &mut [], &mut []);
            }
    
            // First, find at what point do we split between the first and 2nd slice. Easy with
            // ptr.align_offset.
            let ptr = self.as_ptr();
            // SAFETY: Here we are ensuring we will use aligned pointers for U for the
            // rest of the method. This is done by passing a pointer to &[T] with an
            // alignment targeted for U.
            // `crate::ptr::align_offset` is called with a correctly aligned and
            // valid pointer `ptr` (it comes from a reference to `self`) and with
            // a size that is a power of two (since it comes from the alignment for U),
            // satisfying its safety constraints.
            let offset = unsafe { crate::ptr::align_offset(ptr, mem::align_of::<U>()) };
            if offset > self.len() {
                (self, &mut [], &mut [])
            } else {
                let (left, rest) = self.split_at_mut(offset);
                let (us_len, ts_len) = rest.align_to_offsets::<U>();
                let rest_len = rest.len();
                let mut_ptr = rest.as_mut_ptr();
                // Inform Miri that we want to consider the "middle" pointer to be suitably aligned.
                #[cfg(miri)]
                crate::intrinsics::miri_promise_symbolic_alignment(
                    mut_ptr.cast() as *const (),
                    mem::align_of::<U>(),
                );
                // We can't use `rest` again after this, that would invalidate its alias `mut_ptr`!
                // SAFETY: see comments for `align_to`.
                unsafe {
                    (
                        left,
                        from_raw_parts_mut(mut_ptr as *mut U, us_len),
                        from_raw_parts_mut(mut_ptr.add(rest_len - ts_len), ts_len),
                    )
                }
            }
        }
    *)
    Definition align_to_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ U ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) 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 (|
                                LogicalOp.or (|
                                  M.read (|
                                    M.get_constant (| "core::mem::SizedTypeProperties::IS_ZST" |)
                                  |),
                                  ltac:(M.monadic
                                    (M.read (|
                                      M.get_constant (| "core::mem::SizedTypeProperties::IS_ZST" |)
                                    |)))
                                |)
                              |)) 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.Tuple
                                    [
                                      M.read (| self |);
                                      M.alloc (| Value.Array [] |);
                                      M.alloc (| Value.Array [] |)
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ ptr :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "slice") [] [ T ],
                        "as_ptr",
                        []
                      |),
                      [ M.read (| self |) ]
                    |)
                  |) in
                let~ offset :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::ptr::align_offset", [ T ] |),
                      [
                        M.read (| ptr |);
                        M.call_closure (| M.get_function (| "core::mem::align_of", [ U ] |), [] |)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.gt (|
                                M.read (| offset |),
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ T ],
                                    "len",
                                    []
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          Value.Tuple
                            [
                              M.read (| self |);
                              M.alloc (| Value.Array [] |);
                              M.alloc (| Value.Array [] |)
                            ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ T ],
                                "split_at_mut",
                                []
                              |),
                              [ M.read (| self |); M.read (| offset |) ]
                            |)
                          |),
                          [
                            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 left := M.copy (| γ0_0 |) in
                                let rest := M.copy (| γ0_1 |) in
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ T ],
                                        "align_to_offsets",
                                        [ U ]
                                      |),
                                      [ M.read (| rest |) ]
                                    |)
                                  |),
                                  [
                                    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 us_len := M.copy (| γ0_0 |) in
                                        let ts_len := M.copy (| γ0_1 |) in
                                        let~ rest_len :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.apply (Ty.path "slice") [] [ T ],
                                                "len",
                                                []
                                              |),
                                              [ M.read (| rest |) ]
                                            |)
                                          |) in
                                        let~ mut_ptr :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.apply (Ty.path "slice") [] [ T ],
                                                "as_mut_ptr",
                                                []
                                              |),
                                              [ M.read (| rest |) ]
                                            |)
                                          |) in
                                        M.alloc (|
                                          Value.Tuple
                                            [
                                              M.read (| left |);
                                              M.call_closure (|
                                                M.get_function (|
                                                  "core::slice::raw::from_raw_parts_mut",
                                                  [ U ]
                                                |),
                                                [
                                                  M.rust_cast (M.read (| mut_ptr |));
                                                  M.read (| us_len |)
                                                ]
                                              |);
                                              M.call_closure (|
                                                M.get_function (|
                                                  "core::slice::raw::from_raw_parts_mut",
                                                  [ T ]
                                                |),
                                                [
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply (Ty.path "*mut") [] [ T ],
                                                      "add",
                                                      []
                                                    |),
                                                    [
                                                      M.read (| mut_ptr |);
                                                      BinOp.Wrap.sub (|
                                                        M.read (| rest_len |),
                                                        M.read (| ts_len |)
                                                      |)
                                                    ]
                                                  |);
                                                  M.read (| ts_len |)
                                                ]
                                              |)
                                            ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_align_to_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "align_to_mut" (align_to_mut T).
    
    (*
        pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
        where
            Simd<T, LANES>: AsRef<[T; LANES]>,
            T: simd::SimdElement,
            simd::LaneCount<LANES>: simd::SupportedLaneCount,
        {
            // These are expected to always match, as vector types are laid out like
            // arrays per <https://llvm.org/docs/LangRef.html#vector-type>, but we
            // might as well double-check since it'll optimize away anyhow.
            assert_eq!(mem::size_of::<Simd<T, LANES>>(), mem::size_of::<[T; LANES]>());
    
            // SAFETY: The simd types have the same layout as arrays, just with
            // potentially-higher alignment, so the de-facto transmutes are sound.
            unsafe { self.align_to() }
        }
    *)
    Definition as_simd (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ LANES ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (|
                  Value.Tuple
                    [
                      M.alloc (|
                        M.call_closure (|
                          M.get_function (|
                            "core::mem::size_of",
                            [ Ty.apply (Ty.path "core::core_simd::vector::Simd") [ LANES ] [ T ] ]
                          |),
                          []
                        |)
                      |);
                      M.alloc (|
                        M.call_closure (|
                          M.get_function (|
                            "core::mem::size_of",
                            [ Ty.apply (Ty.path "array") [ LANES ] [ T ] ]
                          |),
                          []
                        |)
                      |)
                    ]
                |),
                [
                  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 left_val := M.copy (| γ0_0 |) in
                      let right_val := M.copy (| γ0_1 |) in
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    UnOp.not (|
                                      BinOp.eq (|
                                        M.read (| M.read (| left_val |) |),
                                        M.read (| M.read (| right_val |) |)
                                      |)
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    let~ kind :=
                                      M.alloc (|
                                        Value.StructTuple "core::panicking::AssertKind::Eq" []
                                      |) in
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_function (|
                                          "core::panicking::assert_failed",
                                          [ Ty.path "usize"; Ty.path "usize" ]
                                        |),
                                        [
                                          M.read (| kind |);
                                          M.read (| left_val |);
                                          M.read (| right_val |);
                                          Value.StructTuple "core::option::Option::None" []
                                        ]
                                      |)
                                    |)
                                  |)
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ T ],
                  "align_to",
                  [ Ty.apply (Ty.path "core::core_simd::vector::Simd") [ LANES ] [ T ] ]
                |),
                [ M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_simd :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_simd" (as_simd T).
    
    (*
        pub fn as_simd_mut<const LANES: usize>(&mut self) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
        where
            Simd<T, LANES>: AsMut<[T; LANES]>,
            T: simd::SimdElement,
            simd::LaneCount<LANES>: simd::SupportedLaneCount,
        {
            // These are expected to always match, as vector types are laid out like
            // arrays per <https://llvm.org/docs/LangRef.html#vector-type>, but we
            // might as well double-check since it'll optimize away anyhow.
            assert_eq!(mem::size_of::<Simd<T, LANES>>(), mem::size_of::<[T; LANES]>());
    
            // SAFETY: The simd types have the same layout as arrays, just with
            // potentially-higher alignment, so the de-facto transmutes are sound.
            unsafe { self.align_to_mut() }
        }
    *)
    Definition as_simd_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ LANES ], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (|
                  Value.Tuple
                    [
                      M.alloc (|
                        M.call_closure (|
                          M.get_function (|
                            "core::mem::size_of",
                            [ Ty.apply (Ty.path "core::core_simd::vector::Simd") [ LANES ] [ T ] ]
                          |),
                          []
                        |)
                      |);
                      M.alloc (|
                        M.call_closure (|
                          M.get_function (|
                            "core::mem::size_of",
                            [ Ty.apply (Ty.path "array") [ LANES ] [ T ] ]
                          |),
                          []
                        |)
                      |)
                    ]
                |),
                [
                  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 left_val := M.copy (| γ0_0 |) in
                      let right_val := M.copy (| γ0_1 |) in
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    UnOp.not (|
                                      BinOp.eq (|
                                        M.read (| M.read (| left_val |) |),
                                        M.read (| M.read (| right_val |) |)
                                      |)
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    let~ kind :=
                                      M.alloc (|
                                        Value.StructTuple "core::panicking::AssertKind::Eq" []
                                      |) in
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_function (|
                                          "core::panicking::assert_failed",
                                          [ Ty.path "usize"; Ty.path "usize" ]
                                        |),
                                        [
                                          M.read (| kind |);
                                          M.read (| left_val |);
                                          M.read (| right_val |);
                                          Value.StructTuple "core::option::Option::None" []
                                        ]
                                      |)
                                    |)
                                  |)
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ T ],
                  "align_to_mut",
                  [ Ty.apply (Ty.path "core::core_simd::vector::Simd") [ LANES ] [ T ] ]
                |),
                [ M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_simd_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "as_simd_mut" (as_simd_mut T).
    
    (*
        pub fn is_sorted(&self) -> bool
        where
            T: PartialOrd,
        {
            self.is_sorted_by(|a, b| a <= b)
        }
    *)
    Definition is_sorted (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "slice") [] [ T ],
              "is_sorted_by",
              [
                Ty.function
                  [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ]; Ty.apply (Ty.path "&") [] [ T ] ] ]
                  (Ty.path "bool")
              ]
            |),
            [
              M.read (| self |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0; α1 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let a := M.copy (| γ |) in
                                M.match_operator (|
                                  M.alloc (| α1 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let b := M.copy (| γ |) in
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::cmp::PartialOrd",
                                            Ty.apply (Ty.path "&") [] [ T ],
                                            [ Ty.apply (Ty.path "&") [] [ T ] ],
                                            "le",
                                            []
                                          |),
                                          [ a; M.alloc (| M.read (| b |) |) ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_sorted :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "is_sorted" (is_sorted T).
    
    (*
        pub fn is_sorted_by<'a, F>(&'a self, mut compare: F) -> bool
        where
            F: FnMut(&'a T, &'a T) -> bool,
        {
            self.array_windows().all(|[a, b]| compare(a, b))
        }
    *)
    Definition is_sorted_by (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F ], [ self; compare ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let compare := M.alloc (| compare |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::iter::traits::iterator::Iterator",
              Ty.apply
                (Ty.path "core::slice::iter::ArrayWindows")
                [ Value.Integer IntegerKind.Usize 2 ]
                [ T ],
              [],
              "all",
              [
                Ty.function
                  [
                    Ty.tuple
                      [
                        Ty.apply
                          (Ty.path "&")
                          []
                          [ Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 2 ] [ T ] ]
                      ]
                  ]
                  (Ty.path "bool")
              ]
            |),
            [
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "array_windows",
                    []
                  |),
                  [ 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 γ := M.read (| γ |) in
                                let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                                let γ1_1 := M.SubPointer.get_slice_index (| γ, 1 |) in
                                let a := M.alloc (| γ1_0 |) in
                                let b := M.alloc (| γ1_1 |) in
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::ops::function::FnMut",
                                    F,
                                    [
                                      Ty.tuple
                                        [
                                          Ty.apply (Ty.path "&") [] [ T ];
                                          Ty.apply (Ty.path "&") [] [ T ]
                                        ]
                                    ],
                                    "call_mut",
                                    []
                                  |),
                                  [ compare; Value.Tuple [ M.read (| a |); M.read (| b |) ] ]
                                |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_sorted_by :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "is_sorted_by" (is_sorted_by T).
    
    (*
        pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
        where
            F: FnMut(&'a T) -> K,
            K: PartialOrd,
        {
            self.iter().is_sorted_by_key(f)
        }
    *)
    Definition is_sorted_by_key
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ F; K ], [ self; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let f := M.alloc (| f |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::iter::traits::iterator::Iterator",
              Ty.apply (Ty.path "core::slice::iter::Iter") [] [ T ],
              [],
              "is_sorted_by_key",
              [ F; K ]
            |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "iter", [] |),
                [ M.read (| self |) ]
              |);
              M.read (| f |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_sorted_by_key :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "is_sorted_by_key" (is_sorted_by_key T).
    
    (*
        pub fn partition_point<P>(&self, mut pred: P) -> usize
        where
            P: FnMut(&T) -> bool,
        {
            self.binary_search_by(|x| if pred(x) { Less } else { Greater }).unwrap_or_else(|i| i)
        }
    *)
    Definition partition_point
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ P ], [ self; pred ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let pred := M.alloc (| pred |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::result::Result") [] [ Ty.path "usize"; Ty.path "usize" ],
              "unwrap_or_else",
              [ Ty.function [ Ty.tuple [ Ty.path "usize" ] ] (Ty.path "usize") ]
            |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ T ],
                  "binary_search_by",
                  [
                    Ty.function
                      [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ T ] ] ]
                      (Ty.path "core::cmp::Ordering")
                  ]
                |),
                [
                  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 x := M.copy (| γ |) in
                                    M.read (|
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    M.call_closure (|
                                                      M.get_trait_method (|
                                                        "core::ops::function::FnMut",
                                                        P,
                                                        [
                                                          Ty.tuple
                                                            [ Ty.apply (Ty.path "&") [] [ T ] ]
                                                        ],
                                                        "call_mut",
                                                        []
                                                      |),
                                                      [ pred; Value.Tuple [ M.read (| x |) ] ]
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                Value.StructTuple "core::cmp::Ordering::Less" []
                                              |)));
                                          fun γ =>
                                            ltac:(M.monadic
                                              (M.alloc (|
                                                Value.StructTuple "core::cmp::Ordering::Greater" []
                                              |)))
                                        ]
                                      |)
                                    |)))
                              ]
                            |)))
                        | _ => M.impossible "wrong number of arguments"
                        end))
                ]
              |);
              M.closure
                (fun γ =>
                  ltac:(M.monadic
                    match γ with
                    | [ α0 ] =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (| α0 |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let i := M.copy (| γ |) in
                                M.read (| i |)))
                          ]
                        |)))
                    | _ => M.impossible "wrong number of arguments"
                    end))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_partition_point :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "partition_point" (partition_point T).
    
    (*
        pub fn take<'a, R: OneSidedRange<usize>>(self: &mut &'a Self, range: R) -> Option<&'a Self> {
            let (direction, split_index) = split_point_of(range)?;
            if split_index > self.len() {
                return None;
            }
            let (front, back) = self.split_at(split_index);
            match direction {
                Direction::Front => {
                    *self = back;
                    Some(front)
                }
                Direction::Back => {
                    *self = front;
                    Some(back)
                }
            }
        }
    *)
    Definition take (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ R ], [ self; range ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let range := M.alloc (| range |) 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 "core::slice::Direction"; Ty.path "usize" ] ],
                          [],
                          "branch",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_function (| "core::slice::split_point_of", [ R ] |),
                            [ M.read (| range |) ]
                          |)
                        ]
                      |)
                    |),
                    [
                      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.apply
                                            (Ty.path "&")
                                            []
                                            [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                        ],
                                      [
                                        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 direction := M.copy (| γ0_0 |) in
                        let split_index := M.copy (| γ0_1 |) in
                        let~ _ :=
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ :=
                                    M.use
                                      (M.alloc (|
                                        BinOp.gt (|
                                          M.read (| split_index |),
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ T ],
                                              "len",
                                              []
                                            |),
                                            [ M.read (| M.read (| self |) |) ]
                                          |)
                                        |)
                                      |)) 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.StructTuple "core::option::Option::None" []
                                        |)
                                      |)
                                    |)
                                  |)));
                              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") [] [ T ],
                                "split_at",
                                []
                              |),
                              [ M.read (| M.read (| self |) |); M.read (| split_index |) ]
                            |)
                          |),
                          [
                            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 front := M.copy (| γ0_0 |) in
                                let back := M.copy (| γ0_1 |) in
                                M.match_operator (|
                                  direction,
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (|
                                            γ,
                                            "core::slice::Direction::Front"
                                          |) in
                                        let~ _ :=
                                          M.write (| M.read (| self |), M.read (| back |) |) in
                                        M.alloc (|
                                          Value.StructTuple
                                            "core::option::Option::Some"
                                            [ M.read (| front |) ]
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (|
                                            γ,
                                            "core::slice::Direction::Back"
                                          |) in
                                        let~ _ :=
                                          M.write (| M.read (| self |), M.read (| front |) |) in
                                        M.alloc (|
                                          Value.StructTuple
                                            "core::option::Option::Some"
                                            [ M.read (| back |) ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_take :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "take" (take T).
    
    (*
        pub fn take_mut<'a, R: OneSidedRange<usize>>(
            self: &mut &'a mut Self,
            range: R,
        ) -> Option<&'a mut Self> {
            let (direction, split_index) = split_point_of(range)?;
            if split_index > self.len() {
                return None;
            }
            let (front, back) = mem::take(self).split_at_mut(split_index);
            match direction {
                Direction::Front => {
                    *self = back;
                    Some(front)
                }
                Direction::Back => {
                    *self = front;
                    Some(back)
                }
            }
        }
    *)
    Definition take_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [ R ], [ self; range ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let range := M.alloc (| range |) 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 "core::slice::Direction"; Ty.path "usize" ] ],
                          [],
                          "branch",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_function (| "core::slice::split_point_of", [ R ] |),
                            [ M.read (| range |) ]
                          |)
                        ]
                      |)
                    |),
                    [
                      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.apply
                                            (Ty.path "&mut")
                                            []
                                            [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                        ],
                                      [
                                        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 direction := M.copy (| γ0_0 |) in
                        let split_index := M.copy (| γ0_1 |) in
                        let~ _ :=
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ :=
                                    M.use
                                      (M.alloc (|
                                        BinOp.gt (|
                                          M.read (| split_index |),
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ T ],
                                              "len",
                                              []
                                            |),
                                            [ M.read (| M.read (| self |) |) ]
                                          |)
                                        |)
                                      |)) 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.StructTuple "core::option::Option::None" []
                                        |)
                                      |)
                                    |)
                                  |)));
                              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") [] [ T ],
                                "split_at_mut",
                                []
                              |),
                              [
                                M.call_closure (|
                                  M.get_function (|
                                    "core::mem::take",
                                    [
                                      Ty.apply
                                        (Ty.path "&mut")
                                        []
                                        [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                    ]
                                  |),
                                  [ M.read (| self |) ]
                                |);
                                M.read (| split_index |)
                              ]
                            |)
                          |),
                          [
                            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 front := M.copy (| γ0_0 |) in
                                let back := M.copy (| γ0_1 |) in
                                M.match_operator (|
                                  direction,
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (|
                                            γ,
                                            "core::slice::Direction::Front"
                                          |) in
                                        let~ _ :=
                                          M.write (| M.read (| self |), M.read (| back |) |) in
                                        M.alloc (|
                                          Value.StructTuple
                                            "core::option::Option::Some"
                                            [ M.read (| front |) ]
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (|
                                            γ,
                                            "core::slice::Direction::Back"
                                          |) in
                                        let~ _ :=
                                          M.write (| M.read (| self |), M.read (| front |) |) in
                                        M.alloc (|
                                          Value.StructTuple
                                            "core::option::Option::Some"
                                            [ M.read (| back |) ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_take_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "take_mut" (take_mut T).
    
    (*
        pub fn take_first<'a>(self: &mut &'a Self) -> Option<&'a T> {
            let (first, rem) = self.split_first()?;
            *self = rem;
            Some(first)
        }
    *)
    Definition take_first (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) 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.apply (Ty.path "&") [] [ T ];
                                  Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                ]
                            ],
                          [],
                          "branch",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "slice") [] [ T ],
                              "split_first",
                              []
                            |),
                            [ M.read (| 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.apply (Ty.path "&") [] [ T ] ],
                                      [
                                        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 first := M.copy (| γ0_0 |) in
                        let rem := M.copy (| γ0_1 |) in
                        let~ _ := M.write (| M.read (| self |), M.read (| rem |) |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| first |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_take_first :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "take_first" (take_first T).
    
    (*
        pub fn take_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
            let (first, rem) = mem::take(self).split_first_mut()?;
            *self = rem;
            Some(first)
        }
    *)
    Definition take_first_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) 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.apply (Ty.path "&mut") [] [ T ];
                                  Ty.apply
                                    (Ty.path "&mut")
                                    []
                                    [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                ]
                            ],
                          [],
                          "branch",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "slice") [] [ T ],
                              "split_first_mut",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_function (|
                                  "core::mem::take",
                                  [
                                    Ty.apply
                                      (Ty.path "&mut")
                                      []
                                      [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                  ]
                                |),
                                [ 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.apply (Ty.path "&mut") [] [ T ] ],
                                      [
                                        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 first := M.copy (| γ0_0 |) in
                        let rem := M.copy (| γ0_1 |) in
                        let~ _ := M.write (| M.read (| self |), M.read (| rem |) |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| first |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_take_first_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "take_first_mut" (take_first_mut T).
    
    (*
        pub fn take_last<'a>(self: &mut &'a Self) -> Option<&'a T> {
            let (last, rem) = self.split_last()?;
            *self = rem;
            Some(last)
        }
    *)
    Definition take_last (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) 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.apply (Ty.path "&") [] [ T ];
                                  Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                ]
                            ],
                          [],
                          "branch",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "slice") [] [ T ],
                              "split_last",
                              []
                            |),
                            [ M.read (| 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.apply (Ty.path "&") [] [ T ] ],
                                      [
                                        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 last := M.copy (| γ0_0 |) in
                        let rem := M.copy (| γ0_1 |) in
                        let~ _ := M.write (| M.read (| self |), M.read (| rem |) |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| last |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_take_last :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "take_last" (take_last T).
    
    (*
        pub fn take_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
            let (last, rem) = mem::take(self).split_last_mut()?;
            *self = rem;
            Some(last)
        }
    *)
    Definition take_last_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) 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.apply (Ty.path "&mut") [] [ T ];
                                  Ty.apply
                                    (Ty.path "&mut")
                                    []
                                    [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                ]
                            ],
                          [],
                          "branch",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "slice") [] [ T ],
                              "split_last_mut",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_function (|
                                  "core::mem::take",
                                  [
                                    Ty.apply
                                      (Ty.path "&mut")
                                      []
                                      [ Ty.apply (Ty.path "slice") [] [ T ] ]
                                  ]
                                |),
                                [ 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.apply (Ty.path "&mut") [] [ T ] ],
                                      [
                                        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 last := M.copy (| γ0_0 |) in
                        let rem := M.copy (| γ0_1 |) in
                        let~ _ := M.write (| M.read (| self |), M.read (| rem |) |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| last |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_take_last_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "take_last_mut" (take_last_mut T).
    
    (*
        pub unsafe fn get_many_unchecked_mut<const N: usize>(
            &mut self,
            indices: [usize; N],
        ) -> [&mut T; N] {
            // NB: This implementation is written as it is because any variation of
            // `indices.map(|i| self.get_unchecked_mut(i))` would make miri unhappy,
            // or generate worse code otherwise. This is also why we need to go
            // through a raw pointer here.
            let slice: *mut [T] = self;
            let mut arr: mem::MaybeUninit<[&mut T; N]> = mem::MaybeUninit::uninit();
            let arr_ptr = arr.as_mut_ptr();
    
            // SAFETY: We expect `indices` to contain disjunct values that are
            // in bounds of `self`.
            unsafe {
                for i in 0..N {
                    let idx = *indices.get_unchecked(i);
                    *( *arr_ptr).get_unchecked_mut(i) = &mut *slice.get_unchecked_mut(idx);
                }
                arr.assume_init()
            }
        }
    *)
    Definition get_many_unchecked_mut
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self; indices ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let indices := M.alloc (| indices |) in
          M.read (|
            let~ slice := M.alloc (| M.read (| self |) |) in
            let~ arr :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply
                      (Ty.path "core::mem::maybe_uninit::MaybeUninit")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.apply (Ty.path "&mut") [] [ T ] ] ],
                    "uninit",
                    []
                  |),
                  []
                |)
              |) in
            let~ arr_ptr :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply
                      (Ty.path "core::mem::maybe_uninit::MaybeUninit")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.apply (Ty.path "&mut") [] [ T ] ] ],
                    "as_mut_ptr",
                    []
                  |),
                  [ arr ]
                |)
              |) in
            let~ _ :=
              M.use
                (M.match_operator (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::iter::traits::collect::IntoIterator",
                        Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ],
                        [],
                        "into_iter",
                        []
                      |),
                      [
                        Value.StructRecord
                          "core::ops::range::Range"
                          [
                            ("start", Value.Integer IntegerKind.Usize 0);
                            ("end_",
                              M.read (|
                                M.get_constant (| "core::slice::get_many_unchecked_mut::N" |)
                              |))
                          ]
                      ]
                    |)
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let iter := M.copy (| γ |) in
                        M.loop (|
                          ltac:(M.monadic
                            (let~ _ :=
                              M.match_operator (|
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::iter::traits::iterator::Iterator",
                                      Ty.apply
                                        (Ty.path "core::ops::range::Range")
                                        []
                                        [ Ty.path "usize" ],
                                      [],
                                      "next",
                                      []
                                    |),
                                    [ iter ]
                                  |)
                                |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let _ :=
                                        M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                      M.alloc (|
                                        M.never_to_any (| M.read (| M.break (||) |) |)
                                      |)));
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ0_0 :=
                                        M.SubPointer.get_struct_tuple_field (|
                                          γ,
                                          "core::option::Option::Some",
                                          0
                                        |) in
                                      let i := M.copy (| γ0_0 |) in
                                      let~ idx :=
                                        M.copy (|
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ Ty.path "usize" ],
                                              "get_unchecked",
                                              [ Ty.path "usize" ]
                                            |),
                                            [ indices; M.read (| i |) ]
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply
                                                (Ty.path "slice")
                                                []
                                                [ Ty.apply (Ty.path "&mut") [] [ T ] ],
                                              "get_unchecked_mut",
                                              [ Ty.path "usize" ]
                                            |),
                                            [ M.read (| arr_ptr |); M.read (| i |) ]
                                          |),
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply
                                                (Ty.path "*mut")
                                                []
                                                [ Ty.apply (Ty.path "slice") [] [ T ] ],
                                              "get_unchecked_mut",
                                              [ Ty.path "usize" ]
                                            |),
                                            [ M.read (| slice |); M.read (| idx |) ]
                                          |)
                                        |) in
                                      M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            M.alloc (| Value.Tuple [] |)))
                        |)))
                  ]
                |)) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply
                    (Ty.path "core::mem::maybe_uninit::MaybeUninit")
                    []
                    [ Ty.apply (Ty.path "array") [ N ] [ Ty.apply (Ty.path "&mut") [] [ T ] ] ],
                  "assume_init",
                  []
                |),
                [ M.read (| arr |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_get_many_unchecked_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "get_many_unchecked_mut" (get_many_unchecked_mut T).
    
    (*
        pub fn get_many_mut<const N: usize>(
            &mut self,
            indices: [usize; N],
        ) -> Result<[&mut T; N], GetManyMutError<N>> {
            if !get_many_check_valid(&indices, self.len()) {
                return Err(GetManyMutError { _private: () });
            }
            // SAFETY: The `get_many_check_valid()` call checked that all indices
            // are disjunct and in bounds.
            unsafe { Ok(self.get_many_unchecked_mut(indices)) }
        }
    *)
    Definition get_many_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [ N ], [], [ self; indices ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let indices := M.alloc (| indices |) 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 (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_function (| "core::slice::get_many_check_valid", [] |),
                                    [
                                      indices;
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "slice") [] [ T ],
                                          "len",
                                          []
                                        |),
                                        [ M.read (| self |) ]
                                      |)
                                    ]
                                  |)
                                |)
                              |)) 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.StructTuple
                                    "core::result::Result::Err"
                                    [
                                      Value.StructRecord
                                        "core::slice::GetManyMutError"
                                        [ ("_private", Value.Tuple []) ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                M.alloc (|
                  Value.StructTuple
                    "core::result::Result::Ok"
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ T ],
                          "get_many_unchecked_mut",
                          []
                        |),
                        [ M.read (| self |); M.read (| indices |) ]
                      |)
                    ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_get_many_mut :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "get_many_mut" (get_many_mut T).
    
    (*
        pub fn elem_offset(&self, element: &T) -> Option<usize> {
            if T::IS_ZST {
                panic!("elements are zero-sized");
            }
    
            let self_start = self.as_ptr() as usize;
            let elem_start = element as *const T as usize;
    
            let byte_offset = elem_start.wrapping_sub(self_start);
    
            if byte_offset % mem::size_of::<T>() != 0 {
                return None;
            }
    
            let offset = byte_offset / mem::size_of::<T>();
    
            if offset < self.len() { Some(offset) } else { None }
        }
    *)
    Definition elem_offset (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; element ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let element := M.alloc (| element |) 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.get_constant (| "core::mem::SizedTypeProperties::IS_ZST" |)) 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_const",
                                      []
                                    |),
                                    [
                                      M.alloc (|
                                        Value.Array
                                          [ M.read (| Value.String "elements are zero-sized" |) ]
                                      |)
                                    ]
                                  |)
                                ]
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ self_start :=
                  M.alloc (|
                    M.rust_cast
                      (M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ T ],
                          "as_ptr",
                          []
                        |),
                        [ M.read (| self |) ]
                      |))
                  |) in
                let~ elem_start :=
                  M.alloc (|
                    M.rust_cast (M.read (| M.use (M.alloc (| M.read (| element |) |)) |))
                  |) in
                let~ byte_offset :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "usize", "wrapping_sub", [] |),
                      [ M.read (| elem_start |); M.read (| self_start |) ]
                    |)
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.ne (|
                                  BinOp.Wrap.rem (|
                                    M.read (| byte_offset |),
                                    M.call_closure (|
                                      M.get_function (| "core::mem::size_of", [ T ] |),
                                      []
                                    |)
                                  |),
                                  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.StructTuple "core::option::Option::None" [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ offset :=
                  M.alloc (|
                    BinOp.Wrap.div (|
                      M.read (| byte_offset |),
                      M.call_closure (| M.get_function (| "core::mem::size_of", [ T ] |), [] |)
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.lt (|
                                M.read (| offset |),
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ T ],
                                    "len",
                                    []
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| offset |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_elem_offset :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "elem_offset" (elem_offset T).
    
    (*
        pub fn subslice_range(&self, subslice: &[T]) -> Option<Range<usize>> {
            if T::IS_ZST {
                panic!("elements are zero-sized");
            }
    
            let self_start = self.as_ptr() as usize;
            let subslice_start = subslice.as_ptr() as usize;
    
            let byte_start = subslice_start.wrapping_sub(self_start);
    
            if byte_start % core::mem::size_of::<T>() != 0 {
                return None;
            }
    
            let start = byte_start / core::mem::size_of::<T>();
            let end = start.wrapping_add(subslice.len());
    
            if start <= self.len() && end <= self.len() { Some(start..end) } else { None }
        }
    *)
    Definition subslice_range
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; subslice ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let subslice := M.alloc (| subslice |) 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.get_constant (| "core::mem::SizedTypeProperties::IS_ZST" |)) 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_const",
                                      []
                                    |),
                                    [
                                      M.alloc (|
                                        Value.Array
                                          [ M.read (| Value.String "elements are zero-sized" |) ]
                                      |)
                                    ]
                                  |)
                                ]
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ self_start :=
                  M.alloc (|
                    M.rust_cast
                      (M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ T ],
                          "as_ptr",
                          []
                        |),
                        [ M.read (| self |) ]
                      |))
                  |) in
                let~ subslice_start :=
                  M.alloc (|
                    M.rust_cast
                      (M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ T ],
                          "as_ptr",
                          []
                        |),
                        [ M.read (| subslice |) ]
                      |))
                  |) in
                let~ byte_start :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "usize", "wrapping_sub", [] |),
                      [ M.read (| subslice_start |); M.read (| self_start |) ]
                    |)
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.ne (|
                                  BinOp.Wrap.rem (|
                                    M.read (| byte_start |),
                                    M.call_closure (|
                                      M.get_function (| "core::mem::size_of", [ T ] |),
                                      []
                                    |)
                                  |),
                                  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.StructTuple "core::option::Option::None" [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ start :=
                  M.alloc (|
                    BinOp.Wrap.div (|
                      M.read (| byte_start |),
                      M.call_closure (| M.get_function (| "core::mem::size_of", [ T ] |), [] |)
                    |)
                  |) in
                let~ end_ :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "usize", "wrapping_add", [] |),
                      [
                        M.read (| start |);
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ T ],
                            "len",
                            []
                          |),
                          [ M.read (| subslice |) ]
                        |)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              LogicalOp.and (|
                                BinOp.le (|
                                  M.read (| start |),
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ T ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |)
                                |),
                                ltac:(M.monadic
                                  (BinOp.le (|
                                    M.read (| end_ |),
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ T ],
                                        "len",
                                        []
                                      |),
                                      [ M.read (| self |) ]
                                    |)
                                  |)))
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          Value.StructTuple
                            "core::option::Option::Some"
                            [
                              Value.StructRecord
                                "core::ops::range::Range"
                                [ ("start", M.read (| start |)); ("end_", M.read (| end_ |)) ]
                            ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_subslice_range :
      forall (T : Ty.t),
      M.IsAssociatedFunction (Self T) "subslice_range" (subslice_range T).
  End Impl_slice_T.
  
  Module Impl_slice_array_N_T.
    Definition Self (N : Value.t) (T : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "slice") [] [ Ty.apply (Ty.path "array") [ N ] [ T ] ].
    
    (*
        pub const fn as_flattened(&self) -> &[T] {
            let len = if T::IS_ZST {
                self.len().checked_mul(N).expect("slice len overflow")
            } else {
                // SAFETY: `self.len() * N` cannot overflow because `self` is
                // already in the address space.
                unsafe { self.len().unchecked_mul(N) }
            };
            // SAFETY: `[T]` is layout-identical to `[T; N]`
            unsafe { from_raw_parts(self.as_ptr().cast(), len) }
        }
    *)
    Definition as_flattened
        (N : Value.t)
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self N T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ len :=
              M.copy (|
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use (M.get_constant (| "core::mem::SizedTypeProperties::IS_ZST" |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::option::Option") [] [ Ty.path "usize" ],
                              "expect",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "usize", "checked_mul", [] |),
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "slice")
                                        []
                                        [ Ty.apply (Ty.path "array") [ N ] [ T ] ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |);
                                  M.read (| M.get_constant (| "core::slice::N" |) |)
                                ]
                              |);
                              M.read (| Value.String "slice len overflow" |)
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "usize", "unchecked_mul", [] |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    []
                                    [ Ty.apply (Ty.path "array") [ N ] [ T ] ],
                                  "len",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |);
                              M.read (| M.get_constant (| "core::slice::N" |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::slice::raw::from_raw_parts", [ T ] |),
                [
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "*const") [] [ Ty.apply (Ty.path "array") [ N ] [ T ] ],
                      "cast",
                      [ T ]
                    |),
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ Ty.apply (Ty.path "array") [ N ] [ T ] ],
                          "as_ptr",
                          []
                        |),
                        [ M.read (| self |) ]
                      |)
                    ]
                  |);
                  M.read (| len |)
                ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_flattened :
      forall (N : Value.t) (T : Ty.t),
      M.IsAssociatedFunction (Self N T) "as_flattened" (as_flattened N T).
    
    (*
        pub fn as_flattened_mut(&mut self) -> &mut [T] {
            let len = if T::IS_ZST {
                self.len().checked_mul(N).expect("slice len overflow")
            } else {
                // SAFETY: `self.len() * N` cannot overflow because `self` is
                // already in the address space.
                unsafe { self.len().unchecked_mul(N) }
            };
            // SAFETY: `[T]` is layout-identical to `[T; N]`
            unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), len) }
        }
    *)
    Definition as_flattened_mut
        (N : Value.t)
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self N T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ len :=
              M.copy (|
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use (M.get_constant (| "core::mem::SizedTypeProperties::IS_ZST" |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::option::Option") [] [ Ty.path "usize" ],
                              "expect",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "usize", "checked_mul", [] |),
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "slice")
                                        []
                                        [ Ty.apply (Ty.path "array") [ N ] [ T ] ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |);
                                  M.read (| M.get_constant (| "core::slice::N" |) |)
                                ]
                              |);
                              M.read (| Value.String "slice len overflow" |)
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "usize", "unchecked_mul", [] |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    []
                                    [ Ty.apply (Ty.path "array") [ N ] [ T ] ],
                                  "len",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |);
                              M.read (| M.get_constant (| "core::slice::N" |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::slice::raw::from_raw_parts_mut", [ T ] |),
                [
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "*mut") [] [ Ty.apply (Ty.path "array") [ N ] [ T ] ],
                      "cast",
                      [ T ]
                    |),
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ Ty.apply (Ty.path "array") [ N ] [ T ] ],
                          "as_mut_ptr",
                          []
                        |),
                        [ M.read (| self |) ]
                      |)
                    ]
                  |);
                  M.read (| len |)
                ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_flattened_mut :
      forall (N : Value.t) (T : Ty.t),
      M.IsAssociatedFunction (Self N T) "as_flattened_mut" (as_flattened_mut N T).
  End Impl_slice_array_N_T.
  
  Module Impl_slice_f32.
    Definition Self : Ty.t := Ty.apply (Ty.path "slice") [] [ Ty.path "f32" ].
    
    (*
        pub fn sort_floats(&mut self) {
            self.sort_unstable_by(f32::total_cmp);
        }
    *)
    Definition sort_floats (ε : 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~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ Ty.path "f32" ],
                    "sort_unstable_by",
                    [
                      Ty.function
                        [
                          Ty.apply (Ty.path "&") [] [ Ty.path "f32" ];
                          Ty.apply (Ty.path "&") [] [ Ty.path "f32" ]
                        ]
                        (Ty.path "core::cmp::Ordering")
                    ]
                  |),
                  [
                    M.read (| self |);
                    M.get_associated_function (| Ty.path "f32", "total_cmp", [] |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_sort_floats : M.IsAssociatedFunction Self "sort_floats" sort_floats.
  End Impl_slice_f32.
  
  Module Impl_slice_f64.
    Definition Self : Ty.t := Ty.apply (Ty.path "slice") [] [ Ty.path "f64" ].
    
    (*
        pub fn sort_floats(&mut self) {
            self.sort_unstable_by(f64::total_cmp);
        }
    *)
    Definition sort_floats (ε : 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~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ Ty.path "f64" ],
                    "sort_unstable_by",
                    [
                      Ty.function
                        [
                          Ty.apply (Ty.path "&") [] [ Ty.path "f64" ];
                          Ty.apply (Ty.path "&") [] [ Ty.path "f64" ]
                        ]
                        (Ty.path "core::cmp::Ordering")
                    ]
                  |),
                  [
                    M.read (| self |);
                    M.get_associated_function (| Ty.path "f64", "total_cmp", [] |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_sort_floats : M.IsAssociatedFunction Self "sort_floats" sort_floats.
  End Impl_slice_f64.
  
  (* Trait *)
  (* Empty module 'CloneFromSpec' *)
  
  Module Impl_core_slice_CloneFromSpec_where_core_clone_Clone_T_T_for_slice_T.
    Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "slice") [] [ T ].
    
    (*
        default fn spec_clone_from(&mut self, src: &[T]) {
            assert!(self.len() == src.len(), "destination and source slices have different lengths");
            // NOTE: We need to explicitly slice them to the same length
            // to make it easier for the optimizer to elide bounds checking.
            // But since it can't be relied on we also have an explicit specialization for T: Copy.
            let len = self.len();
            let src = &src[..len];
            for i in 0..len {
                self[i].clone_from(&src[i]);
            }
        }
    *)
    Definition spec_clone_from
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; src ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let src := M.alloc (| src |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.eq (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ T ],
                                    "len",
                                    []
                                  |),
                                  [ M.read (| self |) ]
                                |),
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ T ],
                                    "len",
                                    []
                                  |),
                                  [ M.read (| src |) ]
                                |)
                              |)
                            |)
                          |)) 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_const",
                                  []
                                |),
                                [
                                  M.alloc (|
                                    Value.Array
                                      [
                                        M.read (|
                                          Value.String
                                            "destination and source slices have different lengths"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ len :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.apply (Ty.path "slice") [] [ T ], "len", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ src :=
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "core::ops::index::Index",
                    Ty.apply (Ty.path "slice") [] [ T ],
                    [ Ty.apply (Ty.path "core::ops::range::RangeTo") [] [ Ty.path "usize" ] ],
                    "index",
                    []
                  |),
                  [
                    M.read (| src |);
                    Value.StructRecord "core::ops::range::RangeTo" [ ("end_", M.read (| len |)) ]
                  ]
                |)
              |) in
            M.use
              (M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::iter::traits::collect::IntoIterator",
                      Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ],
                      [],
                      "into_iter",
                      []
                    |),
                    [
                      Value.StructRecord
                        "core::ops::range::Range"
                        [ ("start", Value.Integer IntegerKind.Usize 0); ("end_", M.read (| len |)) ]
                    ]
                  |)
                |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let iter := M.copy (| γ |) in
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::iter::traits::iterator::Iterator",
                                    Ty.apply
                                      (Ty.path "core::ops::range::Range")
                                      []
                                      [ Ty.path "usize" ],
                                    [],
                                    "next",
                                    []
                                  |),
                                  [ iter ]
                                |)
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let _ :=
                                      M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                    M.alloc (| M.never_to_any (| M.read (| M.break (||) |) |) |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::option::Option::Some",
                                        0
                                      |) in
                                    let i := M.copy (| γ0_0 |) in
                                    let~ _ :=
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::clone::Clone",
                                            T,
                                            [],
                                            "clone_from",
                                            []
                                          |),
                                          [
                                            M.SubPointer.get_array_field (| M.read (| self |), i |);
                                            M.SubPointer.get_array_field (| M.read (| src |), i |)
                                          ]
                                        |)
                                      |) in
                                    M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)))
                ]
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (T : Ty.t),
      M.IsTraitInstance
        "core::slice::CloneFromSpec"
        (Self T)
        (* Trait polymorphic types *) [ (* T *) T ]
        (* Instance *) [ ("spec_clone_from", InstanceField.Method (spec_clone_from T)) ].
  End Impl_core_slice_CloneFromSpec_where_core_clone_Clone_T_T_for_slice_T.
  
  Module Impl_core_slice_CloneFromSpec_where_core_marker_Copy_T_T_for_slice_T.
    Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "slice") [] [ T ].
    
    (*
        fn spec_clone_from(&mut self, src: &[T]) {
            self.copy_from_slice(src);
        }
    *)
    Definition spec_clone_from
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self; src ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let src := M.alloc (| src |) in
          M.read (|
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ T ],
                    "copy_from_slice",
                    []
                  |),
                  [ M.read (| self |); M.read (| src |) ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (T : Ty.t),
      M.IsTraitInstance
        "core::slice::CloneFromSpec"
        (Self T)
        (* Trait polymorphic types *) [ (* T *) T ]
        (* Instance *) [ ("spec_clone_from", InstanceField.Method (spec_clone_from T)) ].
  End Impl_core_slice_CloneFromSpec_where_core_marker_Copy_T_T_for_slice_T.
  
  Module Impl_core_default_Default_for_ref__slice_T.
    Definition Self (T : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ T ] ].
    
    (*
        fn default() -> Self {
            &[]
        }
    *)
    Definition default (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.alloc (| Value.Array [] |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (T : Ty.t),
      M.IsTraitInstance
        "core::default::Default"
        (Self T)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("default", InstanceField.Method (default T)) ].
  End Impl_core_default_Default_for_ref__slice_T.
  
  Module Impl_core_default_Default_for_ref_mut_slice_T.
    Definition Self (T : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "&mut") [] [ Ty.apply (Ty.path "slice") [] [ T ] ].
    
    (*
        fn default() -> Self {
            &mut []
        }
    *)
    Definition default (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.alloc (| Value.Array [] |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (T : Ty.t),
      M.IsTraitInstance
        "core::default::Default"
        (Self T)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("default", InstanceField.Method (default T)) ].
  End Impl_core_default_Default_for_ref_mut_slice_T.
  
  (* Trait *)
  (* Empty module 'SlicePattern' *)
  
  Module Impl_core_slice_SlicePattern_for_slice_T.
    Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "slice") [] [ T ].
    
    (*     type Item = T; *)
    Definition _Item (T : Ty.t) : Ty.t := T.
    
    (*
        fn as_slice(&self) -> &[Self::Item] {
            self
        }
    *)
    Definition as_slice (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (T : Ty.t),
      M.IsTraitInstance
        "core::slice::SlicePattern"
        (Self T)
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Item", InstanceField.Ty (_Item T)); ("as_slice", InstanceField.Method (as_slice T)) ].
  End Impl_core_slice_SlicePattern_for_slice_T.
  
  Module Impl_core_slice_SlicePattern_for_array_N_T.
    Definition Self (N : Value.t) (T : Ty.t) : Ty.t := Ty.apply (Ty.path "array") [ N ] [ T ].
    
    (*     type Item = T; *)
    Definition _Item (N : Value.t) (T : Ty.t) : Ty.t := T.
    
    (*
        fn as_slice(&self) -> &[Self::Item] {
            self
        }
    *)
    Definition as_slice
        (N : Value.t)
        (T : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self N T in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (N : Value.t) (T : Ty.t),
      M.IsTraitInstance
        "core::slice::SlicePattern"
        (Self N T)
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Item", InstanceField.Ty (_Item N T)); ("as_slice", InstanceField.Method (as_slice N T))
        ].
  End Impl_core_slice_SlicePattern_for_array_N_T.
  
  (*
  fn get_many_check_valid<const N: usize>(indices: &[usize; N], len: usize) -> bool {
      // NB: The optimizer should inline the loops into a sequence
      // of instructions without additional branching.
      let mut valid = true;
      for (i, &idx) in indices.iter().enumerate() {
          valid &= idx < len;
          for &idx2 in &indices[..i] {
              valid &= idx != idx2;
          }
      }
      valid
  }
  *)
  Definition get_many_check_valid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [ N ], [], [ indices; len ] =>
      ltac:(M.monadic
        (let indices := M.alloc (| indices |) in
        let len := M.alloc (| len |) in
        M.read (|
          let~ valid := M.alloc (| Value.Bool true |) in
          let~ _ :=
            M.use
              (M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::iter::traits::collect::IntoIterator",
                      Ty.apply
                        (Ty.path "core::iter::adapters::enumerate::Enumerate")
                        []
                        [ Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "usize" ] ],
                      [],
                      "into_iter",
                      []
                    |),
                    [
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "usize" ],
                          [],
                          "enumerate",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "slice") [] [ Ty.path "usize" ],
                              "iter",
                              []
                            |),
                            [ M.read (| indices |) ]
                          |)
                        ]
                      |)
                    ]
                  |)
                |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let iter := M.copy (| γ |) in
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::iter::traits::iterator::Iterator",
                                    Ty.apply
                                      (Ty.path "core::iter::adapters::enumerate::Enumerate")
                                      []
                                      [
                                        Ty.apply
                                          (Ty.path "core::slice::iter::Iter")
                                          []
                                          [ Ty.path "usize" ]
                                      ],
                                    [],
                                    "next",
                                    []
                                  |),
                                  [ iter ]
                                |)
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let _ :=
                                      M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                    M.alloc (| M.never_to_any (| M.read (| M.break (||) |) |) |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (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 i := M.copy (| γ1_0 |) in
                                    let γ1_1 := M.read (| γ1_1 |) in
                                    let idx := M.copy (| γ1_1 |) in
                                    let~ _ :=
                                      let β := valid in
                                      M.write (|
                                        β,
                                        BinOp.bit_and
                                          (M.read (| β |))
                                          (BinOp.lt (| M.read (| idx |), M.read (| len |) |))
                                      |) in
                                    M.use
                                      (M.match_operator (|
                                        M.alloc (|
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::iter::traits::collect::IntoIterator",
                                              Ty.apply
                                                (Ty.path "&")
                                                []
                                                [ Ty.apply (Ty.path "slice") [] [ Ty.path "usize" ]
                                                ],
                                              [],
                                              "into_iter",
                                              []
                                            |),
                                            [
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::index::Index",
                                                  Ty.apply
                                                    (Ty.path "array")
                                                    [ N ]
                                                    [ Ty.path "usize" ],
                                                  [
                                                    Ty.apply
                                                      (Ty.path "core::ops::range::RangeTo")
                                                      []
                                                      [ Ty.path "usize" ]
                                                  ],
                                                  "index",
                                                  []
                                                |),
                                                [
                                                  M.read (| indices |);
                                                  Value.StructRecord
                                                    "core::ops::range::RangeTo"
                                                    [ ("end_", M.read (| i |)) ]
                                                ]
                                              |)
                                            ]
                                          |)
                                        |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let iter := M.copy (| γ |) in
                                              M.loop (|
                                                ltac:(M.monadic
                                                  (let~ _ :=
                                                    M.match_operator (|
                                                      M.alloc (|
                                                        M.call_closure (|
                                                          M.get_trait_method (|
                                                            "core::iter::traits::iterator::Iterator",
                                                            Ty.apply
                                                              (Ty.path "core::slice::iter::Iter")
                                                              []
                                                              [ Ty.path "usize" ],
                                                            [],
                                                            "next",
                                                            []
                                                          |),
                                                          [ iter ]
                                                        |)
                                                      |),
                                                      [
                                                        fun γ =>
                                                          ltac:(M.monadic
                                                            (let _ :=
                                                              M.is_struct_tuple (|
                                                                γ,
                                                                "core::option::Option::None"
                                                              |) in
                                                            M.alloc (|
                                                              M.never_to_any (|
                                                                M.read (| M.break (||) |)
                                                              |)
                                                            |)));
                                                        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 idx2 := M.copy (| γ0_0 |) in
                                                            let~ _ :=
                                                              let β := valid in
                                                              M.write (|
                                                                β,
                                                                BinOp.bit_and
                                                                  (M.read (| β |))
                                                                  (BinOp.ne (|
                                                                    M.read (| idx |),
                                                                    M.read (| idx2 |)
                                                                  |))
                                                              |) in
                                                            M.alloc (| Value.Tuple [] |)))
                                                      ]
                                                    |) in
                                                  M.alloc (| Value.Tuple [] |)))
                                              |)))
                                        ]
                                      |))))
                              ]
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)))
                ]
              |)) in
          valid
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_get_many_check_valid :
    M.IsFunction "core::slice::get_many_check_valid" get_many_check_valid.
  
  (* StructRecord
    {
      name := "GetManyMutError";
      const_params := [ "N" ];
      ty_params := [];
      fields := [ ("_private", Ty.tuple []) ];
    } *)
  
  Module Impl_core_fmt_Debug_for_core_slice_GetManyMutError_N.
    Definition Self (N : Value.t) : Ty.t :=
      Ty.apply (Ty.path "core::slice::GetManyMutError") [ N ] [].
    
    (*
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("GetManyMutError").finish_non_exhaustive()
        }
    *)
    Definition fmt (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self N in
      match ε, τ, α with
      | [], [], [ self; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let f := M.alloc (| f |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.path "core::fmt::builders::DebugStruct",
              "finish_non_exhaustive",
              []
            |),
            [
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "core::fmt::Formatter",
                    "debug_struct",
                    []
                  |),
                  [ M.read (| f |); M.read (| Value.String "GetManyMutError" |) ]
                |)
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (N : Value.t),
      M.IsTraitInstance
        "core::fmt::Debug"
        (Self N)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("fmt", InstanceField.Method (fmt N)) ].
  End Impl_core_fmt_Debug_for_core_slice_GetManyMutError_N.
  
  Module Impl_core_fmt_Display_for_core_slice_GetManyMutError_N.
    Definition Self (N : Value.t) : Ty.t :=
      Ty.apply (Ty.path "core::slice::GetManyMutError") [ N ] [].
    
    (*
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            fmt::Display::fmt("an index is out of bounds or appeared multiple times in the array", f)
        }
    *)
    Definition fmt (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self N in
      match ε, τ, α with
      | [], [], [ self; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let f := M.alloc (| f |) in
          M.call_closure (|
            M.get_trait_method (| "core::fmt::Display", Ty.path "str", [], "fmt", [] |),
            [
              M.read (|
                Value.String "an index is out of bounds or appeared multiple times in the array"
              |);
              M.read (| f |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (N : Value.t),
      M.IsTraitInstance
        "core::fmt::Display"
        (Self N)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("fmt", InstanceField.Method (fmt N)) ].
  End Impl_core_fmt_Display_for_core_slice_GetManyMutError_N.
End slice.
