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

Module num.
  Module Impl_i8.
    Definition Self : Ty.t := Ty.path "i8".
    
    (*         pub const MIN: Self = !Self::MAX; *)
    (* Ty.path "i8" *)
    Definition value_MIN : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (| UnOp.not (| M.read (| M.get_constant (| "core::num::MAX" |) |) |) |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = (<$UnsignedT>::MAX >> 1) as Self; *)
    (* Ty.path "i8" *)
    Definition value_MAX : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.rust_cast
              (BinOp.Wrap.shr (|
                M.read (| M.get_constant (| "core::num::MAX" |) |),
                Value.Integer IntegerKind.I32 1
              |))
          |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = <$UnsignedT>::BITS; *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run ltac:(M.monadic (M.get_constant (| "core::num::BITS" |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*         pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "count_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                (self as $UnsignedT).leading_zeros()
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "leading_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                (self as $UnsignedT).trailing_zeros()
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "trailing_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (self as $UnsignedT).leading_ones()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "leading_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (self as $UnsignedT).trailing_ones()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "trailing_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_unsigned(self) -> $UnsignedT {
                self as $UnsignedT
            }
    *)
    Definition cast_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_unsigned :
      M.IsAssociatedFunction Self "cast_unsigned" cast_unsigned.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_left(n) as Self
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u8", "rotate_left", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_right(n) as Self
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u8", "rotate_right", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                (self as $UnsignedT).swap_bytes() as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u8", "swap_bytes", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                (self as $UnsignedT).reverse_bits() as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u8", "reverse_bits", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_add(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "i8" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_unsigned :
      M.IsAssociatedFunction Self "checked_add_unsigned" checked_add_unsigned.
    
    (*
            pub const fn strict_add_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_unsigned :
      M.IsAssociatedFunction Self "strict_add_unsigned" strict_add_unsigned.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_sub(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "i8" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_sub_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub_unsigned :
      M.IsAssociatedFunction Self "checked_sub_unsigned" checked_sub_unsigned.
    
    (*
            pub const fn strict_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub_unsigned :
      M.IsAssociatedFunction Self "strict_sub_unsigned" strict_sub_unsigned.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
            }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "i8" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I8 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.I8 (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "i8" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I8 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I8 (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "i8", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div_euclid(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I8 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.I8 (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "i8" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I8 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I8 (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "i8", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem_euclid(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const unsafe fn unchecked_neg(self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"),
                    (
                        lhs: $SelfT = self,
                    ) => !lhs.overflowing_neg().1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(0, self)
                }
            }
    *)
    Definition unchecked_neg (ε : 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.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.unchecked_neg",
                              []
                            |),
                            [ M.read (| self |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "i8" ] |),
                [ Value.Integer IntegerKind.I8 0; M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_neg :
      M.IsAssociatedFunction Self "unchecked_neg" unchecked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "i8"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i8", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.I8 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "i8"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits.
    
                    // SAFETY:
                    // `Self::BITS-1` is guaranteed to be less than `Self::BITS`
                    unsafe { self.unchecked_shr(Self::BITS - 1) }
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i8", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i8", "unchecked_shr", [] |),
                        [
                          M.read (| self |);
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |)
                        ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_abs(self) -> Option<Self> {
                if self.is_negative() {
                    self.checked_neg()
                } else {
                    Some(self)
                }
            }
    *)
    Definition checked_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i8", "checked_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_abs : M.IsAssociatedFunction Self "checked_abs" checked_abs.
    
    (*
            pub const fn strict_abs(self) -> Self {
                if self.is_negative() {
                    self.strict_neg()
                } else {
                    self
                }
            }
    *)
    Definition strict_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i8", "strict_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_abs : M.IsAssociatedFunction Self "strict_abs" strict_abs.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.I8 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I8 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "i8",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "i8",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I8 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I8 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "i8",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "i8", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn checked_isqrt(self) -> Option<Self> {
                if self < 0 {
                    None
                } else {
                    // SAFETY: Input is nonnegative in this `else` branch.
                    let result = unsafe {
                        crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT
                    };
    
                    // Inform the optimizer what the range of outputs is. If
                    // testing `core` crashes with no panic message and a
                    // `num::int_sqrt::i*` test failed, it's because your edits
                    // caused these assertions to become false.
                    //
                    // SAFETY: Integer square root is a monotonically nondecreasing
                    // function, which means that increasing the input will never
                    // cause the output to decrease. Thus, since the input for
                    // nonnegative signed integers is bounded by
                    // `[0, <$ActualT>::MAX]`, sqrt(n) will be bounded by
                    // `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                    unsafe {
                        // SAFETY: `<$ActualT>::MAX` is nonnegative.
                        const MAX_RESULT: $SelfT = unsafe {
                            crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
                        };
    
                        crate::hint::assert_unchecked(result >= 0);
                        crate::hint::assert_unchecked(result <= MAX_RESULT);
                    }
    
                    Some(result)
                }
            }
    *)
    Definition checked_isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I8 0 |)
                        |)) 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~ result :=
                      M.copy (|
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::num::int_sqrt::i8", [] |),
                              [ M.read (| M.use self |) ]
                            |)
                          |))
                      |) in
                    let~ _ :=
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [ BinOp.ge (| M.read (| result |), Value.Integer IntegerKind.I8 0 |) ]
                          |)
                        |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [
                              BinOp.le (|
                                M.read (| result |),
                                M.read (|
                                  M.get_constant (| "core::num::checked_isqrt::MAX_RESULT" |)
                                |)
                              |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| result |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_isqrt :
      M.IsAssociatedFunction Self "checked_isqrt" checked_isqrt.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "i8" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the upper bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_add_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "checked_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_unsigned :
      M.IsAssociatedFunction Self "saturating_add_unsigned" saturating_add_unsigned.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "i8" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the lower bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_sub_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MIN,
                }
            }
    *)
    Definition saturating_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "checked_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MIN" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub_unsigned :
      M.IsAssociatedFunction Self "saturating_sub_unsigned" saturating_sub_unsigned.
    
    (*
            pub const fn saturating_neg(self) -> Self {
                intrinsics::saturating_sub(0, self)
            }
    *)
    Definition saturating_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "i8" ] |),
            [ Value.Integer IntegerKind.I8 0; M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_neg :
      M.IsAssociatedFunction Self "saturating_neg" saturating_neg.
    
    (*
            pub const fn saturating_abs(self) -> Self {
                if self.is_negative() {
                    self.saturating_neg()
                } else {
                    self
                }
            }
    *)
    Definition saturating_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i8", "saturating_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_abs :
      M.IsAssociatedFunction Self "saturating_abs" saturating_abs.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => if (self < 0) == (rhs < 0) {
                        Self::MAX
                    } else {
                        Self::MIN
                    }
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    BinOp.lt (|
                                      M.read (| self |),
                                      Value.Integer IntegerKind.I8 0
                                    |),
                                    BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I8 0 |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.get_constant (| "core::num::MAX" |)));
                        fun γ => ltac:(M.monadic (M.get_constant (| "core::num::MIN" |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                match self.overflowing_div(rhs) {
                    (result, false) => result,
                    (_result, true) => Self::MAX, // MIN / -1 is the only possible saturating overflow
                }
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool false |) in
                    result));
                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 _result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool true |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None if self < 0 && exp % 2 == 1 => Self::MIN,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    let γ :=
                      M.alloc (|
                        BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I8 0 |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    let γ :=
                      M.alloc (|
                        BinOp.eq (|
                          BinOp.Wrap.rem (| M.read (| exp |), Value.Integer IntegerKind.U32 2 |),
                          Value.Integer IntegerKind.U32 1
                        |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.get_constant (| "core::num::MIN" |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "i8" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_unsigned :
      M.IsAssociatedFunction Self "wrapping_add_unsigned" wrapping_add_unsigned.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "i8" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_sub(rhs as Self)
            }
    *)
    Definition wrapping_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "wrapping_sub", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub_unsigned :
      M.IsAssociatedFunction Self "wrapping_sub_unsigned" wrapping_sub_unsigned.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "i8" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self.overflowing_div(rhs).0
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self.overflowing_div_euclid(rhs).0
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self.overflowing_rem(rhs).0
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self.overflowing_rem_euclid(rhs).0
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "wrapping_sub", [] |),
            [ M.read (| M.use (M.alloc (| Value.Integer IntegerKind.I8 0 |)) |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_abs(self) -> Self {
                 if self.is_negative() {
                     self.wrapping_neg()
                 } else {
                     self
                 }
            }
    *)
    Definition wrapping_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i8", "wrapping_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_abs : M.IsAssociatedFunction Self "wrapping_abs" wrapping_abs.
    
    (*
            pub const fn unsigned_abs(self) -> $UnsignedT {
                 self.wrapping_abs() as $UnsignedT
            }
    *)
    Definition unsigned_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "i8", "wrapping_abs", [] |),
              [ M.read (| self |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unsigned_abs : M.IsAssociatedFunction Self "unsigned_abs" unsigned_abs.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I8 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I8 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "i8",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "i8",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "i8", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "i8",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "i8",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "i8" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b != d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i8", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_add(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I8 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_unsigned :
      M.IsAssociatedFunction Self "overflowing_add_unsigned" overflowing_add_unsigned.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "i8" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b != d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i8", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn overflowing_sub_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_sub(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I8 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub_unsigned :
      M.IsAssociatedFunction Self "overflowing_sub_unsigned" overflowing_sub_unsigned.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "i8" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self / rhs, false)
                }
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I8 (-1) |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self.div_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I8 (-1) |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self % rhs, false)
                }
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I8 (-1) |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.I8 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self.rem_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I8 (-1) |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.I8 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                if unlikely!(self == Self::MIN) {
                    (Self::MIN, true)
                } else {
                    (-self, false)
                }
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.eq (|
                                M.read (| self |),
                                M.read (| M.get_constant (| "core::num::MIN" |) |)
                              |)
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [ M.read (| M.get_constant (| "core::num::MIN" |) |); Value.Bool true ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple [ UnOp.neg (| M.read (| self |) |); Value.Bool false ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i8", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i8", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_abs(self) -> (Self, bool) {
                (self.wrapping_abs(), self == Self::MIN)
            }
    *)
    Definition overflowing_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i8", "wrapping_abs", [] |),
                [ M.read (| self |) ]
              |);
              BinOp.eq (| M.read (| self |), M.read (| M.get_constant (| "core::num::MIN" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_abs :
      M.IsAssociatedFunction Self "overflowing_abs" overflowing_abs.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0 {
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple [ Value.Integer IntegerKind.I8 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I8 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "i8",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "i8", "overflowing_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I8 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I8 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                match self.checked_isqrt() {
                    Some(sqrt) => sqrt,
                    None => crate::num::int_sqrt::panic_for_negative_argument(),
                }
            }
    *)
    Definition isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i8", "checked_isqrt", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let sqrt := M.copy (| γ0_0 |) in
                    sqrt));
                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::num::int_sqrt::panic_for_negative_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                let q = self / rhs;
                if self % rhs < 0 {
                    return if rhs > 0 { q - 1 } else { q + 1 }
                }
                q
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ q := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                                  Value.Integer IntegerKind.I8 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_ (|
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.gt (|
                                                    M.read (| rhs |),
                                                    Value.Integer IntegerKind.I8 0
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.alloc (|
                                              BinOp.Wrap.sub (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.I8 1
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              BinOp.Wrap.add (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.I8 1
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                q
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                let r = self % rhs;
                if r < 0 {
                    // Semantically equivalent to `if rhs < 0 { r - rhs } else { r + rhs }`.
                    // If `rhs` is not `Self::MIN`, then `r + abs(rhs)` will not overflow
                    // and is clearly equivalent, because `r` is negative.
                    // Otherwise, `rhs` is `Self::MIN`, then we have
                    // `r.wrapping_add(Self::MIN.wrapping_abs())`, which evaluates
                    // to `r.wrapping_add(Self::MIN)`, which is equivalent to
                    // `r - Self::MIN`, which is what we wanted (and will not overflow
                    // for negative `r`).
                    r.wrapping_add(rhs.wrapping_abs())
                } else {
                    r
                }
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| r |), Value.Integer IntegerKind.I8 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i8", "wrapping_add", [] |),
                        [
                          M.read (| r |);
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "wrapping_abs", [] |),
                            [ M.read (| rhs |) ]
                          |)
                        ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic r)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // If the remainder is non-zero, we need to subtract one if the
                // signs of self and rhs differ, as this means we rounded upwards
                // instead of downwards. We do this branchlessly by creating a mask
                // which is all-ones iff the signs differ, and 0 otherwise. Then by
                // adding this mask (which corresponds to the signed value -1), we
                // get our correction.
                let correction = (self ^ rhs) >> (Self::BITS - 1);
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.shr (|
                  BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                  BinOp.Wrap.sub (|
                    M.read (| M.get_constant (| "core::num::BITS" |) |),
                    Value.Integer IntegerKind.U32 1
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.I8 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // When remainder is non-zero we have a.div_ceil(b) == 1 + a.div_floor(b),
                // so we can re-use the algorithm from div_floor, just adding 1.
                let correction = 1 + ((self ^ rhs) >> (Self::BITS - 1));
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.add (|
                  Value.Integer IntegerKind.I8 1,
                  BinOp.Wrap.shr (|
                    BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                    BinOp.Wrap.sub (|
                      M.read (| M.get_constant (| "core::num::BITS" |) |),
                      Value.Integer IntegerKind.U32 1
                    |)
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.I8 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return self;
                }
    
                let r = self % rhs;
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    self
                } else {
                    self + (rhs - m)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I8 (-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_ (| M.read (| self |) |) |) |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (| M.read (| r |), Value.Integer IntegerKind.I8 0 |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.I8 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.I8 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.I8 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.I8 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        self));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          BinOp.Wrap.add (|
                            M.read (| self |),
                            BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return Some(self);
                }
    
                let r = try_opt!(self.checked_rem(rhs));
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    // r + rhs cannot overflow because they have opposite signs
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    Some(self)
                } else {
                    // rhs - m cannot overflow because m has the same sign as rhs
                    self.checked_add(rhs - m)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I8 (-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.StructTuple
                                    "core::option::Option::Some"
                                    [ M.read (| self |) ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i8", "checked_rem", [] |),
                          [ M.read (| self |); M.read (| rhs |) ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let x := M.copy (| γ0_0 |) in
                            x));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                                |)
                              |)
                            |)))
                      ]
                    |)
                  |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (| M.read (| r |), Value.Integer IntegerKind.I8 0 |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.I8 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.I8 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.I8 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.I8 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn midpoint(self, rhs: Self) -> Self {
                const U: $UnsignedT = <$SelfT>::MIN.unsigned_abs();
    
                // Map an $SelfT to an $UnsignedT
                // ex: i8 [-128; 127] to [0; 255]
                const fn map(a: $SelfT) -> $UnsignedT {
                    (a as $UnsignedT) ^ U
                }
    
                // Map an $UnsignedT to an $SelfT
                // ex: u8 [0; 255] to [-128; 127]
                const fn demap(a: $UnsignedT) -> $SelfT {
                    (a ^ U) as $SelfT
                }
    
                demap(<$UnsignedT>::midpoint(map(self), map(rhs)))
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Self, "demap.midpoint", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u8", "midpoint", [] |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| self |) ]
                  |);
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| rhs |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.I8 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i8", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i8", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i8", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else {
                    // Delegate to the unsigned implementation.
                    // The condition makes sure that both casts are exact.
                    (self as $UnsignedT).checked_ilog(base as $UnsignedT)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.I8 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.I8 1 |)))
                          |)
                        |)) 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 (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u8", "checked_ilog", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| base |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                if self <= 0 {
                    None
                } else {
                    // SAFETY: We just checked that this number is positive
                    let log = (Self::BITS - 1) - unsafe { intrinsics::ctlz_nonzero(self) as u32 };
                    Some(log)
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.le (| M.read (| self |), Value.Integer IntegerKind.I8 0 |)
                        |)) 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~ log :=
                      M.alloc (|
                        BinOp.Wrap.sub (|
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |),
                          M.read (|
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_function (|
                                    "core::intrinsics::ctlz_nonzero",
                                    [ Ty.path "i8" ]
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |))
                          |)
                        |)
                      |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| log |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                if self > 0 {
                    Some(int_log10::$ActualT(self as $ActualT))
                } else {
                    None
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.I8 0 |)
                        |)) 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_function (| "core::num::int_log10::i8", [] |),
                            [ M.read (| M.use self |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn abs(self) -> Self {
                // Note that the #[rustc_inherit_overflow_checks] and #[inline]
                // above mean that the overflow semantics of the subtraction
                // depend on the crate we're being called from.
                if self.is_negative() {
                    -self
                } else {
                    self
                }
            }
    *)
    Definition abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i8", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| UnOp.neg (| M.read (| self |) |) |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs : M.IsAssociatedFunction Self "abs" abs.
    
    (*
            pub const fn abs_diff(self, other: Self) -> $UnsignedT {
                if self < other {
                    // Converting a non-negative x from signed to unsigned by using
                    // `x as U` is left unchanged, but a negative x is converted
                    // to value x + 2^N. Thus if `s` and `o` are binary variables
                    // respectively indicating whether `self` and `other` are
                    // negative, we are computing the mathematical value:
                    //
                    //    (other + o*2^N) - (self + s*2^N)    mod  2^N
                    //    other - self + (o-s)*2^N            mod  2^N
                    //    other - self                        mod  2^N
                    //
                    // Finally, taking the mod 2^N of the mathematical value of
                    // `other - self` does not change it as it already is
                    // in the range [0, 2^N).
                    (other as $UnsignedT).wrapping_sub(self as $UnsignedT)
                } else {
                    (self as $UnsignedT).wrapping_sub(other as $UnsignedT)
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| other |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u8", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| other |)); M.rust_cast (M.read (| self |)) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u8", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn signum(self) -> Self {
                // Picking the right way to phrase this is complicated
                // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>)
                // so delegate it to `Ord` which is already producing -1/0/+1
                // exactly like we need and can be the place to deal with the complexity.
    
                // FIXME(const-hack): replace with cmp
                if self < 0 { -1 }
                else if self == 0 { 0 }
                else { 1 }
            }
    *)
    Definition signum (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I8 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Integer IntegerKind.I8 (-1) |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.I8 0 |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| Value.Integer IntegerKind.I8 0 |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.I8 1 |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_signum : M.IsAssociatedFunction Self "signum" signum.
    
    (*         pub const fn is_positive(self) -> bool { self > 0 } *)
    Definition is_positive (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.I8 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_positive : M.IsAssociatedFunction Self "is_positive" is_positive.
    
    (*         pub const fn is_negative(self) -> bool { self < 0 } *)
    Definition is_negative (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I8 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_negative : M.IsAssociatedFunction Self "is_negative" is_negative.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i8", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i8", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "i8";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 1 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i8", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i8", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 1 ] [ Ty.path "u8" ];
                Ty.path "i8"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*
            pub const fn min_value() -> Self {
                Self::MIN
            }
    *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*
            pub const fn max_value() -> Self {
                Self::MAX
            }
    *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    (*
                pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                    use self::IntErrorKind::*;
                    use self::ParseIntError as PIE;
    
                    if 2 > radix || radix > 36 {
                        from_str_radix_panic(radix);
                    }
    
                    if src.is_empty() {
                        return Err(PIE { kind: Empty });
                    }
    
                    #[allow(unused_comparisons)]
                    let is_signed_ty = 0 > <$int_ty>::MIN;
    
                    // all valid digits are ascii, so we will just iterate over the utf8 bytes
                    // and cast them to chars. .to_digit() will safely return None for anything
                    // other than a valid ascii digit for the given radix, including the first-byte
                    // of multi-byte sequences
                    let src = src.as_bytes();
    
                    let (is_positive, mut digits) = match src {
                        [b'+' | b'-'] => {
                            return Err(PIE { kind: InvalidDigit });
                        }
                        [b'+', rest @ ..] => (true, rest),
                        [b'-', rest @ ..] if is_signed_ty => (false, rest),
                        _ => (true, src),
                    };
    
                    let mut result = 0;
    
                    macro_rules! unwrap_or_PIE {
                        ($option:expr, $kind:ident) => {
                            match $option {
                                Some(value) => value,
                                None => return Err(PIE { kind: $kind }),
                            }
                        };
                    }
    
                    if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
                        // If the len of the str is short compared to the range of the type
                        // we are parsing into, then we can be certain that an overflow will not occur.
                        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
                        // above is a faster (conservative) approximation of this.
                        //
                        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
                        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
                        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
                        macro_rules! run_unchecked_loop {
                            ($unchecked_additive_op:tt) => {{
                                while let [c, rest @ ..] = digits {
                                    result = result * (radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit);
                                    result = result $unchecked_additive_op (x as $int_ty);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_unchecked_loop!(+)
                        } else {
                            run_unchecked_loop!(-)
                        };
                    } else {
                        macro_rules! run_checked_loop {
                            ($checked_additive_op:ident, $overflow_err:ident) => {{
                                while let [c, rest @ ..] = digits {
                                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
                                    // the compiler can use shifts if `radix` can be expressed as a
                                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
                                    // When the compiler can't use these optimisations,
                                    // the latency of the multiplication can be hidden by issuing it
                                    // before the result is needed to improve performance on
                                    // modern out-of-order CPU as multiplication here is slower
                                    // than the other instructions, we can get the end result faster
                                    // doing multiplication first and let the CPU spends other cycles
                                    // doing other computation and get multiplication result later.
                                    let mul = result.checked_mul(radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit) as $int_ty;
                                    result = unwrap_or_PIE!(mul, $overflow_err);
                                    result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_checked_loop!(checked_add, PosOverflow)
                        } else {
                            run_checked_loop!(checked_sub, NegOverflow)
                        };
                    }
                    Ok(result)
                }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) 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 (|
                                  BinOp.gt (|
                                    Value.Integer IntegerKind.U32 2,
                                    M.read (| radix |)
                                  |),
                                  ltac:(M.monadic
                                    (BinOp.gt (|
                                      M.read (| radix |),
                                      Value.Integer IntegerKind.U32 36
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::num::from_str_radix_panic", [] |),
                                [ M.read (| radix |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                                  [ M.read (| src |) ]
                                |)
                              |)) 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::num::error::ParseIntError"
                                        [
                                          ("kind",
                                            Value.StructTuple
                                              "core::num::error::IntErrorKind::Empty"
                                              [])
                                        ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ is_signed_ty :=
                  M.alloc (|
                    BinOp.gt (|
                      Value.Integer IntegerKind.I8 0,
                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                    |)
                  |) in
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| src |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.match_operator (|
                    src,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                          M.find_or_pattern (|
                            γ1_0,
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 43
                                    |) in
                                  Value.Tuple []));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 45
                                    |) in
                                  Value.Tuple []))
                            ],
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [] =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [
                                                  Value.StructRecord
                                                    "core::num::error::ParseIntError"
                                                    [
                                                      ("kind",
                                                        Value.StructTuple
                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                          [])
                                                    ]
                                                ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 43
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          M.alloc (| Value.Tuple [ Value.Bool true; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 45
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          let γ := is_signed_ty in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Tuple [ Value.Bool false; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (| Value.Tuple [ Value.Bool true; M.read (| src |) ] |)))
                    ]
                  |),
                  [
                    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 is_positive := M.copy (| γ0_0 |) in
                        let digits := M.copy (| γ0_1 |) in
                        let~ result := M.alloc (| Value.Integer IntegerKind.I8 0 |) 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::num::can_not_overflow",
                                            [ Ty.path "i8" ]
                                          |),
                                          [
                                            M.read (| radix |);
                                            M.read (| is_signed_ty |);
                                            M.read (| digits |)
                                          ]
                                        |)
                                      |)) 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 is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.add (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.sub (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ := M.use is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "i8",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "i8",
                                                                      "checked_add",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "i8",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "i8",
                                                                      "checked_sub",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_i8.
  
  Module Impl_i16.
    Definition Self : Ty.t := Ty.path "i16".
    
    (*         pub const MIN: Self = !Self::MAX; *)
    (* Ty.path "i16" *)
    Definition value_MIN : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (| UnOp.not (| M.read (| M.get_constant (| "core::num::MAX" |) |) |) |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = (<$UnsignedT>::MAX >> 1) as Self; *)
    (* Ty.path "i16" *)
    Definition value_MAX : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.rust_cast
              (BinOp.Wrap.shr (|
                M.read (| M.get_constant (| "core::num::MAX" |) |),
                Value.Integer IntegerKind.I32 1
              |))
          |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = <$UnsignedT>::BITS; *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run ltac:(M.monadic (M.get_constant (| "core::num::BITS" |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*         pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "count_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                (self as $UnsignedT).leading_zeros()
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "leading_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                (self as $UnsignedT).trailing_zeros()
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "trailing_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (self as $UnsignedT).leading_ones()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "leading_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (self as $UnsignedT).trailing_ones()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "trailing_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_unsigned(self) -> $UnsignedT {
                self as $UnsignedT
            }
    *)
    Definition cast_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_unsigned :
      M.IsAssociatedFunction Self "cast_unsigned" cast_unsigned.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_left(n) as Self
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u16", "rotate_left", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_right(n) as Self
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u16", "rotate_right", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                (self as $UnsignedT).swap_bytes() as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u16", "swap_bytes", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                (self as $UnsignedT).reverse_bits() as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u16", "reverse_bits", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_add(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "i16" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_unsigned :
      M.IsAssociatedFunction Self "checked_add_unsigned" checked_add_unsigned.
    
    (*
            pub const fn strict_add_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_unsigned :
      M.IsAssociatedFunction Self "strict_add_unsigned" strict_add_unsigned.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_sub(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "i16" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_sub_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub_unsigned :
      M.IsAssociatedFunction Self "checked_sub_unsigned" checked_sub_unsigned.
    
    (*
            pub const fn strict_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub_unsigned :
      M.IsAssociatedFunction Self "strict_sub_unsigned" strict_sub_unsigned.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
            }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "i16" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I16 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.I16 (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "i16" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I16 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I16 (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "i16", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div_euclid(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I16 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.I16 (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "i16" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I16 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I16 (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "i16", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem_euclid(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const unsafe fn unchecked_neg(self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"),
                    (
                        lhs: $SelfT = self,
                    ) => !lhs.overflowing_neg().1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(0, self)
                }
            }
    *)
    Definition unchecked_neg (ε : 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.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.unchecked_neg",
                              []
                            |),
                            [ M.read (| self |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "i16" ] |),
                [ Value.Integer IntegerKind.I16 0; M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_neg :
      M.IsAssociatedFunction Self "unchecked_neg" unchecked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "i16"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i16", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.I16 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "i16"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits.
    
                    // SAFETY:
                    // `Self::BITS-1` is guaranteed to be less than `Self::BITS`
                    unsafe { self.unchecked_shr(Self::BITS - 1) }
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i16", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i16", "unchecked_shr", [] |),
                        [
                          M.read (| self |);
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |)
                        ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_abs(self) -> Option<Self> {
                if self.is_negative() {
                    self.checked_neg()
                } else {
                    Some(self)
                }
            }
    *)
    Definition checked_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i16", "checked_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_abs : M.IsAssociatedFunction Self "checked_abs" checked_abs.
    
    (*
            pub const fn strict_abs(self) -> Self {
                if self.is_negative() {
                    self.strict_neg()
                } else {
                    self
                }
            }
    *)
    Definition strict_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i16", "strict_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_abs : M.IsAssociatedFunction Self "strict_abs" strict_abs.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.I16 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I16 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "i16",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "i16",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I16 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I16 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "i16",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "i16", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn checked_isqrt(self) -> Option<Self> {
                if self < 0 {
                    None
                } else {
                    // SAFETY: Input is nonnegative in this `else` branch.
                    let result = unsafe {
                        crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT
                    };
    
                    // Inform the optimizer what the range of outputs is. If
                    // testing `core` crashes with no panic message and a
                    // `num::int_sqrt::i*` test failed, it's because your edits
                    // caused these assertions to become false.
                    //
                    // SAFETY: Integer square root is a monotonically nondecreasing
                    // function, which means that increasing the input will never
                    // cause the output to decrease. Thus, since the input for
                    // nonnegative signed integers is bounded by
                    // `[0, <$ActualT>::MAX]`, sqrt(n) will be bounded by
                    // `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                    unsafe {
                        // SAFETY: `<$ActualT>::MAX` is nonnegative.
                        const MAX_RESULT: $SelfT = unsafe {
                            crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
                        };
    
                        crate::hint::assert_unchecked(result >= 0);
                        crate::hint::assert_unchecked(result <= MAX_RESULT);
                    }
    
                    Some(result)
                }
            }
    *)
    Definition checked_isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I16 0 |)
                        |)) 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~ result :=
                      M.copy (|
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::num::int_sqrt::i16", [] |),
                              [ M.read (| M.use self |) ]
                            |)
                          |))
                      |) in
                    let~ _ :=
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [ BinOp.ge (| M.read (| result |), Value.Integer IntegerKind.I16 0 |) ]
                          |)
                        |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [
                              BinOp.le (|
                                M.read (| result |),
                                M.read (|
                                  M.get_constant (| "core::num::checked_isqrt::MAX_RESULT" |)
                                |)
                              |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| result |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_isqrt :
      M.IsAssociatedFunction Self "checked_isqrt" checked_isqrt.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "i16" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the upper bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_add_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "checked_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_unsigned :
      M.IsAssociatedFunction Self "saturating_add_unsigned" saturating_add_unsigned.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "i16" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the lower bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_sub_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MIN,
                }
            }
    *)
    Definition saturating_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "checked_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MIN" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub_unsigned :
      M.IsAssociatedFunction Self "saturating_sub_unsigned" saturating_sub_unsigned.
    
    (*
            pub const fn saturating_neg(self) -> Self {
                intrinsics::saturating_sub(0, self)
            }
    *)
    Definition saturating_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "i16" ] |),
            [ Value.Integer IntegerKind.I16 0; M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_neg :
      M.IsAssociatedFunction Self "saturating_neg" saturating_neg.
    
    (*
            pub const fn saturating_abs(self) -> Self {
                if self.is_negative() {
                    self.saturating_neg()
                } else {
                    self
                }
            }
    *)
    Definition saturating_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i16", "saturating_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_abs :
      M.IsAssociatedFunction Self "saturating_abs" saturating_abs.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => if (self < 0) == (rhs < 0) {
                        Self::MAX
                    } else {
                        Self::MIN
                    }
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    BinOp.lt (|
                                      M.read (| self |),
                                      Value.Integer IntegerKind.I16 0
                                    |),
                                    BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I16 0 |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.get_constant (| "core::num::MAX" |)));
                        fun γ => ltac:(M.monadic (M.get_constant (| "core::num::MIN" |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                match self.overflowing_div(rhs) {
                    (result, false) => result,
                    (_result, true) => Self::MAX, // MIN / -1 is the only possible saturating overflow
                }
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool false |) in
                    result));
                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 _result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool true |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None if self < 0 && exp % 2 == 1 => Self::MIN,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    let γ :=
                      M.alloc (|
                        BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I16 0 |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    let γ :=
                      M.alloc (|
                        BinOp.eq (|
                          BinOp.Wrap.rem (| M.read (| exp |), Value.Integer IntegerKind.U32 2 |),
                          Value.Integer IntegerKind.U32 1
                        |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.get_constant (| "core::num::MIN" |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "i16" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_unsigned :
      M.IsAssociatedFunction Self "wrapping_add_unsigned" wrapping_add_unsigned.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "i16" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_sub(rhs as Self)
            }
    *)
    Definition wrapping_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "wrapping_sub", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub_unsigned :
      M.IsAssociatedFunction Self "wrapping_sub_unsigned" wrapping_sub_unsigned.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "i16" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self.overflowing_div(rhs).0
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self.overflowing_div_euclid(rhs).0
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self.overflowing_rem(rhs).0
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self.overflowing_rem_euclid(rhs).0
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "wrapping_sub", [] |),
            [ M.read (| M.use (M.alloc (| Value.Integer IntegerKind.I16 0 |)) |); M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_abs(self) -> Self {
                 if self.is_negative() {
                     self.wrapping_neg()
                 } else {
                     self
                 }
            }
    *)
    Definition wrapping_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i16", "wrapping_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_abs : M.IsAssociatedFunction Self "wrapping_abs" wrapping_abs.
    
    (*
            pub const fn unsigned_abs(self) -> $UnsignedT {
                 self.wrapping_abs() as $UnsignedT
            }
    *)
    Definition unsigned_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "i16", "wrapping_abs", [] |),
              [ M.read (| self |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unsigned_abs : M.IsAssociatedFunction Self "unsigned_abs" unsigned_abs.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I16 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I16 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "i16",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "i16",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "i16", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "i16",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "i16",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "i16" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b != d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i16", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_add(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I16 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_unsigned :
      M.IsAssociatedFunction Self "overflowing_add_unsigned" overflowing_add_unsigned.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "i16" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b != d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i16", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn overflowing_sub_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_sub(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I16 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub_unsigned :
      M.IsAssociatedFunction Self "overflowing_sub_unsigned" overflowing_sub_unsigned.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "i16" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self / rhs, false)
                }
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.I16 (-1)
                                |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self.div_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.I16 (-1)
                                |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self % rhs, false)
                }
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I16 (-1) |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.I16 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self.rem_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I16 (-1) |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.I16 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                if unlikely!(self == Self::MIN) {
                    (Self::MIN, true)
                } else {
                    (-self, false)
                }
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.eq (|
                                M.read (| self |),
                                M.read (| M.get_constant (| "core::num::MIN" |) |)
                              |)
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [ M.read (| M.get_constant (| "core::num::MIN" |) |); Value.Bool true ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple [ UnOp.neg (| M.read (| self |) |); Value.Bool false ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i16", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i16", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_abs(self) -> (Self, bool) {
                (self.wrapping_abs(), self == Self::MIN)
            }
    *)
    Definition overflowing_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i16", "wrapping_abs", [] |),
                [ M.read (| self |) ]
              |);
              BinOp.eq (| M.read (| self |), M.read (| M.get_constant (| "core::num::MIN" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_abs :
      M.IsAssociatedFunction Self "overflowing_abs" overflowing_abs.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0 {
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple [ Value.Integer IntegerKind.I16 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I16 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "i16",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "i16",
                                  "overflowing_mul",
                                  []
                                |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I16 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I16 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                match self.checked_isqrt() {
                    Some(sqrt) => sqrt,
                    None => crate::num::int_sqrt::panic_for_negative_argument(),
                }
            }
    *)
    Definition isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i16", "checked_isqrt", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let sqrt := M.copy (| γ0_0 |) in
                    sqrt));
                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::num::int_sqrt::panic_for_negative_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                let q = self / rhs;
                if self % rhs < 0 {
                    return if rhs > 0 { q - 1 } else { q + 1 }
                }
                q
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ q := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                                  Value.Integer IntegerKind.I16 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_ (|
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.gt (|
                                                    M.read (| rhs |),
                                                    Value.Integer IntegerKind.I16 0
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.alloc (|
                                              BinOp.Wrap.sub (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.I16 1
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              BinOp.Wrap.add (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.I16 1
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                q
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                let r = self % rhs;
                if r < 0 {
                    // Semantically equivalent to `if rhs < 0 { r - rhs } else { r + rhs }`.
                    // If `rhs` is not `Self::MIN`, then `r + abs(rhs)` will not overflow
                    // and is clearly equivalent, because `r` is negative.
                    // Otherwise, `rhs` is `Self::MIN`, then we have
                    // `r.wrapping_add(Self::MIN.wrapping_abs())`, which evaluates
                    // to `r.wrapping_add(Self::MIN)`, which is equivalent to
                    // `r - Self::MIN`, which is what we wanted (and will not overflow
                    // for negative `r`).
                    r.wrapping_add(rhs.wrapping_abs())
                } else {
                    r
                }
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| r |), Value.Integer IntegerKind.I16 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i16", "wrapping_add", [] |),
                        [
                          M.read (| r |);
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "wrapping_abs", [] |),
                            [ M.read (| rhs |) ]
                          |)
                        ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic r)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // If the remainder is non-zero, we need to subtract one if the
                // signs of self and rhs differ, as this means we rounded upwards
                // instead of downwards. We do this branchlessly by creating a mask
                // which is all-ones iff the signs differ, and 0 otherwise. Then by
                // adding this mask (which corresponds to the signed value -1), we
                // get our correction.
                let correction = (self ^ rhs) >> (Self::BITS - 1);
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.shr (|
                  BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                  BinOp.Wrap.sub (|
                    M.read (| M.get_constant (| "core::num::BITS" |) |),
                    Value.Integer IntegerKind.U32 1
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.I16 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // When remainder is non-zero we have a.div_ceil(b) == 1 + a.div_floor(b),
                // so we can re-use the algorithm from div_floor, just adding 1.
                let correction = 1 + ((self ^ rhs) >> (Self::BITS - 1));
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.add (|
                  Value.Integer IntegerKind.I16 1,
                  BinOp.Wrap.shr (|
                    BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                    BinOp.Wrap.sub (|
                      M.read (| M.get_constant (| "core::num::BITS" |) |),
                      Value.Integer IntegerKind.U32 1
                    |)
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.I16 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return self;
                }
    
                let r = self % rhs;
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    self
                } else {
                    self + (rhs - m)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I16 (-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_ (| M.read (| self |) |) |) |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (|
                                        M.read (| r |),
                                        Value.Integer IntegerKind.I16 0
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.I16 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.I16 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.I16 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.I16 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        self));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          BinOp.Wrap.add (|
                            M.read (| self |),
                            BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return Some(self);
                }
    
                let r = try_opt!(self.checked_rem(rhs));
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    // r + rhs cannot overflow because they have opposite signs
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    Some(self)
                } else {
                    // rhs - m cannot overflow because m has the same sign as rhs
                    self.checked_add(rhs - m)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I16 (-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.StructTuple
                                    "core::option::Option::Some"
                                    [ M.read (| self |) ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i16", "checked_rem", [] |),
                          [ M.read (| self |); M.read (| rhs |) ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let x := M.copy (| γ0_0 |) in
                            x));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                                |)
                              |)
                            |)))
                      ]
                    |)
                  |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (|
                                        M.read (| r |),
                                        Value.Integer IntegerKind.I16 0
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.I16 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.I16 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.I16 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.I16 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn midpoint(self, rhs: Self) -> Self {
                const U: $UnsignedT = <$SelfT>::MIN.unsigned_abs();
    
                // Map an $SelfT to an $UnsignedT
                // ex: i8 [-128; 127] to [0; 255]
                const fn map(a: $SelfT) -> $UnsignedT {
                    (a as $UnsignedT) ^ U
                }
    
                // Map an $UnsignedT to an $SelfT
                // ex: u8 [0; 255] to [-128; 127]
                const fn demap(a: $UnsignedT) -> $SelfT {
                    (a ^ U) as $SelfT
                }
    
                demap(<$UnsignedT>::midpoint(map(self), map(rhs)))
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Self, "demap.midpoint", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u16", "midpoint", [] |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| self |) ]
                  |);
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| rhs |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.I16 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i16", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i16", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i16", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else {
                    // Delegate to the unsigned implementation.
                    // The condition makes sure that both casts are exact.
                    (self as $UnsignedT).checked_ilog(base as $UnsignedT)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.I16 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.I16 1 |)))
                          |)
                        |)) 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 (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u16", "checked_ilog", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| base |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                if self <= 0 {
                    None
                } else {
                    // SAFETY: We just checked that this number is positive
                    let log = (Self::BITS - 1) - unsafe { intrinsics::ctlz_nonzero(self) as u32 };
                    Some(log)
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.le (| M.read (| self |), Value.Integer IntegerKind.I16 0 |)
                        |)) 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~ log :=
                      M.alloc (|
                        BinOp.Wrap.sub (|
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |),
                          M.read (|
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_function (|
                                    "core::intrinsics::ctlz_nonzero",
                                    [ Ty.path "i16" ]
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |))
                          |)
                        |)
                      |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| log |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                if self > 0 {
                    Some(int_log10::$ActualT(self as $ActualT))
                } else {
                    None
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.I16 0 |)
                        |)) 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_function (| "core::num::int_log10::i16", [] |),
                            [ M.read (| M.use self |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn abs(self) -> Self {
                // Note that the #[rustc_inherit_overflow_checks] and #[inline]
                // above mean that the overflow semantics of the subtraction
                // depend on the crate we're being called from.
                if self.is_negative() {
                    -self
                } else {
                    self
                }
            }
    *)
    Definition abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i16", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| UnOp.neg (| M.read (| self |) |) |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs : M.IsAssociatedFunction Self "abs" abs.
    
    (*
            pub const fn abs_diff(self, other: Self) -> $UnsignedT {
                if self < other {
                    // Converting a non-negative x from signed to unsigned by using
                    // `x as U` is left unchanged, but a negative x is converted
                    // to value x + 2^N. Thus if `s` and `o` are binary variables
                    // respectively indicating whether `self` and `other` are
                    // negative, we are computing the mathematical value:
                    //
                    //    (other + o*2^N) - (self + s*2^N)    mod  2^N
                    //    other - self + (o-s)*2^N            mod  2^N
                    //    other - self                        mod  2^N
                    //
                    // Finally, taking the mod 2^N of the mathematical value of
                    // `other - self` does not change it as it already is
                    // in the range [0, 2^N).
                    (other as $UnsignedT).wrapping_sub(self as $UnsignedT)
                } else {
                    (self as $UnsignedT).wrapping_sub(other as $UnsignedT)
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| other |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u16", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| other |)); M.rust_cast (M.read (| self |)) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u16", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn signum(self) -> Self {
                // Picking the right way to phrase this is complicated
                // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>)
                // so delegate it to `Ord` which is already producing -1/0/+1
                // exactly like we need and can be the place to deal with the complexity.
    
                // FIXME(const-hack): replace with cmp
                if self < 0 { -1 }
                else if self == 0 { 0 }
                else { 1 }
            }
    *)
    Definition signum (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I16 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Integer IntegerKind.I16 (-1) |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.I16 0 |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| Value.Integer IntegerKind.I16 0 |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.I16 1 |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_signum : M.IsAssociatedFunction Self "signum" signum.
    
    (*         pub const fn is_positive(self) -> bool { self > 0 } *)
    Definition is_positive (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.I16 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_positive : M.IsAssociatedFunction Self "is_positive" is_positive.
    
    (*         pub const fn is_negative(self) -> bool { self < 0 } *)
    Definition is_negative (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I16 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_negative : M.IsAssociatedFunction Self "is_negative" is_negative.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i16", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i16", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "i16";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 2 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i16", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i16", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 2 ] [ Ty.path "u8" ];
                Ty.path "i16"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*
            pub const fn min_value() -> Self {
                Self::MIN
            }
    *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*
            pub const fn max_value() -> Self {
                Self::MAX
            }
    *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    (*
                pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                    use self::IntErrorKind::*;
                    use self::ParseIntError as PIE;
    
                    if 2 > radix || radix > 36 {
                        from_str_radix_panic(radix);
                    }
    
                    if src.is_empty() {
                        return Err(PIE { kind: Empty });
                    }
    
                    #[allow(unused_comparisons)]
                    let is_signed_ty = 0 > <$int_ty>::MIN;
    
                    // all valid digits are ascii, so we will just iterate over the utf8 bytes
                    // and cast them to chars. .to_digit() will safely return None for anything
                    // other than a valid ascii digit for the given radix, including the first-byte
                    // of multi-byte sequences
                    let src = src.as_bytes();
    
                    let (is_positive, mut digits) = match src {
                        [b'+' | b'-'] => {
                            return Err(PIE { kind: InvalidDigit });
                        }
                        [b'+', rest @ ..] => (true, rest),
                        [b'-', rest @ ..] if is_signed_ty => (false, rest),
                        _ => (true, src),
                    };
    
                    let mut result = 0;
    
                    macro_rules! unwrap_or_PIE {
                        ($option:expr, $kind:ident) => {
                            match $option {
                                Some(value) => value,
                                None => return Err(PIE { kind: $kind }),
                            }
                        };
                    }
    
                    if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
                        // If the len of the str is short compared to the range of the type
                        // we are parsing into, then we can be certain that an overflow will not occur.
                        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
                        // above is a faster (conservative) approximation of this.
                        //
                        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
                        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
                        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
                        macro_rules! run_unchecked_loop {
                            ($unchecked_additive_op:tt) => {{
                                while let [c, rest @ ..] = digits {
                                    result = result * (radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit);
                                    result = result $unchecked_additive_op (x as $int_ty);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_unchecked_loop!(+)
                        } else {
                            run_unchecked_loop!(-)
                        };
                    } else {
                        macro_rules! run_checked_loop {
                            ($checked_additive_op:ident, $overflow_err:ident) => {{
                                while let [c, rest @ ..] = digits {
                                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
                                    // the compiler can use shifts if `radix` can be expressed as a
                                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
                                    // When the compiler can't use these optimisations,
                                    // the latency of the multiplication can be hidden by issuing it
                                    // before the result is needed to improve performance on
                                    // modern out-of-order CPU as multiplication here is slower
                                    // than the other instructions, we can get the end result faster
                                    // doing multiplication first and let the CPU spends other cycles
                                    // doing other computation and get multiplication result later.
                                    let mul = result.checked_mul(radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit) as $int_ty;
                                    result = unwrap_or_PIE!(mul, $overflow_err);
                                    result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_checked_loop!(checked_add, PosOverflow)
                        } else {
                            run_checked_loop!(checked_sub, NegOverflow)
                        };
                    }
                    Ok(result)
                }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) 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 (|
                                  BinOp.gt (|
                                    Value.Integer IntegerKind.U32 2,
                                    M.read (| radix |)
                                  |),
                                  ltac:(M.monadic
                                    (BinOp.gt (|
                                      M.read (| radix |),
                                      Value.Integer IntegerKind.U32 36
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::num::from_str_radix_panic", [] |),
                                [ M.read (| radix |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                                  [ M.read (| src |) ]
                                |)
                              |)) 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::num::error::ParseIntError"
                                        [
                                          ("kind",
                                            Value.StructTuple
                                              "core::num::error::IntErrorKind::Empty"
                                              [])
                                        ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ is_signed_ty :=
                  M.alloc (|
                    BinOp.gt (|
                      Value.Integer IntegerKind.I16 0,
                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                    |)
                  |) in
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| src |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.match_operator (|
                    src,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                          M.find_or_pattern (|
                            γ1_0,
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 43
                                    |) in
                                  Value.Tuple []));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 45
                                    |) in
                                  Value.Tuple []))
                            ],
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [] =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [
                                                  Value.StructRecord
                                                    "core::num::error::ParseIntError"
                                                    [
                                                      ("kind",
                                                        Value.StructTuple
                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                          [])
                                                    ]
                                                ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 43
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          M.alloc (| Value.Tuple [ Value.Bool true; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 45
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          let γ := is_signed_ty in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Tuple [ Value.Bool false; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (| Value.Tuple [ Value.Bool true; M.read (| src |) ] |)))
                    ]
                  |),
                  [
                    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 is_positive := M.copy (| γ0_0 |) in
                        let digits := M.copy (| γ0_1 |) in
                        let~ result := M.alloc (| Value.Integer IntegerKind.I16 0 |) 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::num::can_not_overflow",
                                            [ Ty.path "i16" ]
                                          |),
                                          [
                                            M.read (| radix |);
                                            M.read (| is_signed_ty |);
                                            M.read (| digits |)
                                          ]
                                        |)
                                      |)) 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 is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.add (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.sub (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ := M.use is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "i16",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "i16",
                                                                      "checked_add",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "i16",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "i16",
                                                                      "checked_sub",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_i16.
  
  Module Impl_i32.
    Definition Self : Ty.t := Ty.path "i32".
    
    (*         pub const MIN: Self = !Self::MAX; *)
    (* Ty.path "i32" *)
    Definition value_MIN : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (| UnOp.not (| M.read (| M.get_constant (| "core::num::MAX" |) |) |) |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = (<$UnsignedT>::MAX >> 1) as Self; *)
    (* Ty.path "i32" *)
    Definition value_MAX : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.rust_cast
              (BinOp.Wrap.shr (|
                M.read (| M.get_constant (| "core::num::MAX" |) |),
                Value.Integer IntegerKind.I32 1
              |))
          |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = <$UnsignedT>::BITS; *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run ltac:(M.monadic (M.get_constant (| "core::num::BITS" |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*         pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "count_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                (self as $UnsignedT).leading_zeros()
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "leading_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                (self as $UnsignedT).trailing_zeros()
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "trailing_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (self as $UnsignedT).leading_ones()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "leading_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (self as $UnsignedT).trailing_ones()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "trailing_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_unsigned(self) -> $UnsignedT {
                self as $UnsignedT
            }
    *)
    Definition cast_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_unsigned :
      M.IsAssociatedFunction Self "cast_unsigned" cast_unsigned.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_left(n) as Self
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u32", "rotate_left", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_right(n) as Self
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u32", "rotate_right", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                (self as $UnsignedT).swap_bytes() as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u32", "swap_bytes", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                (self as $UnsignedT).reverse_bits() as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u32", "reverse_bits", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_add(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "i32" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_unsigned :
      M.IsAssociatedFunction Self "checked_add_unsigned" checked_add_unsigned.
    
    (*
            pub const fn strict_add_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_unsigned :
      M.IsAssociatedFunction Self "strict_add_unsigned" strict_add_unsigned.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_sub(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "i32" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_sub_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub_unsigned :
      M.IsAssociatedFunction Self "checked_sub_unsigned" checked_sub_unsigned.
    
    (*
            pub const fn strict_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub_unsigned :
      M.IsAssociatedFunction Self "strict_sub_unsigned" strict_sub_unsigned.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
            }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "i32" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I32 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.I32 (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "i32" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I32 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I32 (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "i32", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div_euclid(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I32 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.I32 (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "i32" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I32 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I32 (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "i32", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem_euclid(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const unsafe fn unchecked_neg(self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"),
                    (
                        lhs: $SelfT = self,
                    ) => !lhs.overflowing_neg().1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(0, self)
                }
            }
    *)
    Definition unchecked_neg (ε : 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.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.unchecked_neg",
                              []
                            |),
                            [ M.read (| self |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "i32" ] |),
                [ Value.Integer IntegerKind.I32 0; M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_neg :
      M.IsAssociatedFunction Self "unchecked_neg" unchecked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "i32"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i32", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.I32 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "i32"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits.
    
                    // SAFETY:
                    // `Self::BITS-1` is guaranteed to be less than `Self::BITS`
                    unsafe { self.unchecked_shr(Self::BITS - 1) }
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i32", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i32", "unchecked_shr", [] |),
                        [
                          M.read (| self |);
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |)
                        ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_abs(self) -> Option<Self> {
                if self.is_negative() {
                    self.checked_neg()
                } else {
                    Some(self)
                }
            }
    *)
    Definition checked_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i32", "checked_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_abs : M.IsAssociatedFunction Self "checked_abs" checked_abs.
    
    (*
            pub const fn strict_abs(self) -> Self {
                if self.is_negative() {
                    self.strict_neg()
                } else {
                    self
                }
            }
    *)
    Definition strict_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i32", "strict_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_abs : M.IsAssociatedFunction Self "strict_abs" strict_abs.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.I32 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I32 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "i32",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "i32",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I32 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I32 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "i32",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "i32", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn checked_isqrt(self) -> Option<Self> {
                if self < 0 {
                    None
                } else {
                    // SAFETY: Input is nonnegative in this `else` branch.
                    let result = unsafe {
                        crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT
                    };
    
                    // Inform the optimizer what the range of outputs is. If
                    // testing `core` crashes with no panic message and a
                    // `num::int_sqrt::i*` test failed, it's because your edits
                    // caused these assertions to become false.
                    //
                    // SAFETY: Integer square root is a monotonically nondecreasing
                    // function, which means that increasing the input will never
                    // cause the output to decrease. Thus, since the input for
                    // nonnegative signed integers is bounded by
                    // `[0, <$ActualT>::MAX]`, sqrt(n) will be bounded by
                    // `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                    unsafe {
                        // SAFETY: `<$ActualT>::MAX` is nonnegative.
                        const MAX_RESULT: $SelfT = unsafe {
                            crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
                        };
    
                        crate::hint::assert_unchecked(result >= 0);
                        crate::hint::assert_unchecked(result <= MAX_RESULT);
                    }
    
                    Some(result)
                }
            }
    *)
    Definition checked_isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I32 0 |)
                        |)) 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~ result :=
                      M.copy (|
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::num::int_sqrt::i32", [] |),
                              [ M.read (| M.use self |) ]
                            |)
                          |))
                      |) in
                    let~ _ :=
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [ BinOp.ge (| M.read (| result |), Value.Integer IntegerKind.I32 0 |) ]
                          |)
                        |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [
                              BinOp.le (|
                                M.read (| result |),
                                M.read (|
                                  M.get_constant (| "core::num::checked_isqrt::MAX_RESULT" |)
                                |)
                              |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| result |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_isqrt :
      M.IsAssociatedFunction Self "checked_isqrt" checked_isqrt.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "i32" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the upper bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_add_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "checked_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_unsigned :
      M.IsAssociatedFunction Self "saturating_add_unsigned" saturating_add_unsigned.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "i32" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the lower bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_sub_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MIN,
                }
            }
    *)
    Definition saturating_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "checked_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MIN" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub_unsigned :
      M.IsAssociatedFunction Self "saturating_sub_unsigned" saturating_sub_unsigned.
    
    (*
            pub const fn saturating_neg(self) -> Self {
                intrinsics::saturating_sub(0, self)
            }
    *)
    Definition saturating_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "i32" ] |),
            [ Value.Integer IntegerKind.I32 0; M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_neg :
      M.IsAssociatedFunction Self "saturating_neg" saturating_neg.
    
    (*
            pub const fn saturating_abs(self) -> Self {
                if self.is_negative() {
                    self.saturating_neg()
                } else {
                    self
                }
            }
    *)
    Definition saturating_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i32", "saturating_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_abs :
      M.IsAssociatedFunction Self "saturating_abs" saturating_abs.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => if (self < 0) == (rhs < 0) {
                        Self::MAX
                    } else {
                        Self::MIN
                    }
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    BinOp.lt (|
                                      M.read (| self |),
                                      Value.Integer IntegerKind.I32 0
                                    |),
                                    BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I32 0 |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.get_constant (| "core::num::MAX" |)));
                        fun γ => ltac:(M.monadic (M.get_constant (| "core::num::MIN" |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                match self.overflowing_div(rhs) {
                    (result, false) => result,
                    (_result, true) => Self::MAX, // MIN / -1 is the only possible saturating overflow
                }
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool false |) in
                    result));
                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 _result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool true |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None if self < 0 && exp % 2 == 1 => Self::MIN,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    let γ :=
                      M.alloc (|
                        BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I32 0 |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    let γ :=
                      M.alloc (|
                        BinOp.eq (|
                          BinOp.Wrap.rem (| M.read (| exp |), Value.Integer IntegerKind.U32 2 |),
                          Value.Integer IntegerKind.U32 1
                        |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.get_constant (| "core::num::MIN" |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "i32" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_unsigned :
      M.IsAssociatedFunction Self "wrapping_add_unsigned" wrapping_add_unsigned.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "i32" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_sub(rhs as Self)
            }
    *)
    Definition wrapping_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "wrapping_sub", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub_unsigned :
      M.IsAssociatedFunction Self "wrapping_sub_unsigned" wrapping_sub_unsigned.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "i32" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self.overflowing_div(rhs).0
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self.overflowing_div_euclid(rhs).0
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self.overflowing_rem(rhs).0
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self.overflowing_rem_euclid(rhs).0
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "wrapping_sub", [] |),
            [ M.read (| M.use (M.alloc (| Value.Integer IntegerKind.I32 0 |)) |); M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_abs(self) -> Self {
                 if self.is_negative() {
                     self.wrapping_neg()
                 } else {
                     self
                 }
            }
    *)
    Definition wrapping_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i32", "wrapping_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_abs : M.IsAssociatedFunction Self "wrapping_abs" wrapping_abs.
    
    (*
            pub const fn unsigned_abs(self) -> $UnsignedT {
                 self.wrapping_abs() as $UnsignedT
            }
    *)
    Definition unsigned_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "i32", "wrapping_abs", [] |),
              [ M.read (| self |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unsigned_abs : M.IsAssociatedFunction Self "unsigned_abs" unsigned_abs.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I32 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I32 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "i32",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "i32",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "i32", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "i32",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "i32",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "i32" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b != d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_add(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I32 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_unsigned :
      M.IsAssociatedFunction Self "overflowing_add_unsigned" overflowing_add_unsigned.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "i32" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b != d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn overflowing_sub_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_sub(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I32 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub_unsigned :
      M.IsAssociatedFunction Self "overflowing_sub_unsigned" overflowing_sub_unsigned.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "i32" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self / rhs, false)
                }
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.I32 (-1)
                                |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self.div_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.I32 (-1)
                                |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self % rhs, false)
                }
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I32 (-1) |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.I32 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self.rem_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I32 (-1) |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.I32 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                if unlikely!(self == Self::MIN) {
                    (Self::MIN, true)
                } else {
                    (-self, false)
                }
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.eq (|
                                M.read (| self |),
                                M.read (| M.get_constant (| "core::num::MIN" |) |)
                              |)
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [ M.read (| M.get_constant (| "core::num::MIN" |) |); Value.Bool true ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple [ UnOp.neg (| M.read (| self |) |); Value.Bool false ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i32", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i32", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_abs(self) -> (Self, bool) {
                (self.wrapping_abs(), self == Self::MIN)
            }
    *)
    Definition overflowing_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i32", "wrapping_abs", [] |),
                [ M.read (| self |) ]
              |);
              BinOp.eq (| M.read (| self |), M.read (| M.get_constant (| "core::num::MIN" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_abs :
      M.IsAssociatedFunction Self "overflowing_abs" overflowing_abs.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0 {
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple [ Value.Integer IntegerKind.I32 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I32 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "i32",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "i32",
                                  "overflowing_mul",
                                  []
                                |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I32 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I32 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                match self.checked_isqrt() {
                    Some(sqrt) => sqrt,
                    None => crate::num::int_sqrt::panic_for_negative_argument(),
                }
            }
    *)
    Definition isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i32", "checked_isqrt", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let sqrt := M.copy (| γ0_0 |) in
                    sqrt));
                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::num::int_sqrt::panic_for_negative_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                let q = self / rhs;
                if self % rhs < 0 {
                    return if rhs > 0 { q - 1 } else { q + 1 }
                }
                q
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ q := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                                  Value.Integer IntegerKind.I32 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_ (|
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.gt (|
                                                    M.read (| rhs |),
                                                    Value.Integer IntegerKind.I32 0
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.alloc (|
                                              BinOp.Wrap.sub (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.I32 1
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              BinOp.Wrap.add (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.I32 1
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                q
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                let r = self % rhs;
                if r < 0 {
                    // Semantically equivalent to `if rhs < 0 { r - rhs } else { r + rhs }`.
                    // If `rhs` is not `Self::MIN`, then `r + abs(rhs)` will not overflow
                    // and is clearly equivalent, because `r` is negative.
                    // Otherwise, `rhs` is `Self::MIN`, then we have
                    // `r.wrapping_add(Self::MIN.wrapping_abs())`, which evaluates
                    // to `r.wrapping_add(Self::MIN)`, which is equivalent to
                    // `r - Self::MIN`, which is what we wanted (and will not overflow
                    // for negative `r`).
                    r.wrapping_add(rhs.wrapping_abs())
                } else {
                    r
                }
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| r |), Value.Integer IntegerKind.I32 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i32", "wrapping_add", [] |),
                        [
                          M.read (| r |);
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "wrapping_abs", [] |),
                            [ M.read (| rhs |) ]
                          |)
                        ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic r)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // If the remainder is non-zero, we need to subtract one if the
                // signs of self and rhs differ, as this means we rounded upwards
                // instead of downwards. We do this branchlessly by creating a mask
                // which is all-ones iff the signs differ, and 0 otherwise. Then by
                // adding this mask (which corresponds to the signed value -1), we
                // get our correction.
                let correction = (self ^ rhs) >> (Self::BITS - 1);
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.shr (|
                  BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                  BinOp.Wrap.sub (|
                    M.read (| M.get_constant (| "core::num::BITS" |) |),
                    Value.Integer IntegerKind.U32 1
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.I32 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // When remainder is non-zero we have a.div_ceil(b) == 1 + a.div_floor(b),
                // so we can re-use the algorithm from div_floor, just adding 1.
                let correction = 1 + ((self ^ rhs) >> (Self::BITS - 1));
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.add (|
                  Value.Integer IntegerKind.I32 1,
                  BinOp.Wrap.shr (|
                    BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                    BinOp.Wrap.sub (|
                      M.read (| M.get_constant (| "core::num::BITS" |) |),
                      Value.Integer IntegerKind.U32 1
                    |)
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.I32 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return self;
                }
    
                let r = self % rhs;
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    self
                } else {
                    self + (rhs - m)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I32 (-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_ (| M.read (| self |) |) |) |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (|
                                        M.read (| r |),
                                        Value.Integer IntegerKind.I32 0
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.I32 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.I32 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.I32 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.I32 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        self));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          BinOp.Wrap.add (|
                            M.read (| self |),
                            BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return Some(self);
                }
    
                let r = try_opt!(self.checked_rem(rhs));
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    // r + rhs cannot overflow because they have opposite signs
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    Some(self)
                } else {
                    // rhs - m cannot overflow because m has the same sign as rhs
                    self.checked_add(rhs - m)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I32 (-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.StructTuple
                                    "core::option::Option::Some"
                                    [ M.read (| self |) ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "checked_rem", [] |),
                          [ M.read (| self |); M.read (| rhs |) ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let x := M.copy (| γ0_0 |) in
                            x));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                                |)
                              |)
                            |)))
                      ]
                    |)
                  |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (|
                                        M.read (| r |),
                                        Value.Integer IntegerKind.I32 0
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.I32 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.I32 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.I32 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.I32 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn midpoint(self, rhs: Self) -> Self {
                const U: $UnsignedT = <$SelfT>::MIN.unsigned_abs();
    
                // Map an $SelfT to an $UnsignedT
                // ex: i8 [-128; 127] to [0; 255]
                const fn map(a: $SelfT) -> $UnsignedT {
                    (a as $UnsignedT) ^ U
                }
    
                // Map an $UnsignedT to an $SelfT
                // ex: u8 [0; 255] to [-128; 127]
                const fn demap(a: $UnsignedT) -> $SelfT {
                    (a ^ U) as $SelfT
                }
    
                demap(<$UnsignedT>::midpoint(map(self), map(rhs)))
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Self, "demap.midpoint", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u32", "midpoint", [] |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| self |) ]
                  |);
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| rhs |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.I32 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else {
                    // Delegate to the unsigned implementation.
                    // The condition makes sure that both casts are exact.
                    (self as $UnsignedT).checked_ilog(base as $UnsignedT)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.I32 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.I32 1 |)))
                          |)
                        |)) 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 (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u32", "checked_ilog", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| base |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                if self <= 0 {
                    None
                } else {
                    // SAFETY: We just checked that this number is positive
                    let log = (Self::BITS - 1) - unsafe { intrinsics::ctlz_nonzero(self) as u32 };
                    Some(log)
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.le (| M.read (| self |), Value.Integer IntegerKind.I32 0 |)
                        |)) 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~ log :=
                      M.alloc (|
                        BinOp.Wrap.sub (|
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |),
                          M.read (|
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_function (|
                                    "core::intrinsics::ctlz_nonzero",
                                    [ Ty.path "i32" ]
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |))
                          |)
                        |)
                      |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| log |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                if self > 0 {
                    Some(int_log10::$ActualT(self as $ActualT))
                } else {
                    None
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.I32 0 |)
                        |)) 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_function (| "core::num::int_log10::i32", [] |),
                            [ M.read (| M.use self |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn abs(self) -> Self {
                // Note that the #[rustc_inherit_overflow_checks] and #[inline]
                // above mean that the overflow semantics of the subtraction
                // depend on the crate we're being called from.
                if self.is_negative() {
                    -self
                } else {
                    self
                }
            }
    *)
    Definition abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i32", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| UnOp.neg (| M.read (| self |) |) |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs : M.IsAssociatedFunction Self "abs" abs.
    
    (*
            pub const fn abs_diff(self, other: Self) -> $UnsignedT {
                if self < other {
                    // Converting a non-negative x from signed to unsigned by using
                    // `x as U` is left unchanged, but a negative x is converted
                    // to value x + 2^N. Thus if `s` and `o` are binary variables
                    // respectively indicating whether `self` and `other` are
                    // negative, we are computing the mathematical value:
                    //
                    //    (other + o*2^N) - (self + s*2^N)    mod  2^N
                    //    other - self + (o-s)*2^N            mod  2^N
                    //    other - self                        mod  2^N
                    //
                    // Finally, taking the mod 2^N of the mathematical value of
                    // `other - self` does not change it as it already is
                    // in the range [0, 2^N).
                    (other as $UnsignedT).wrapping_sub(self as $UnsignedT)
                } else {
                    (self as $UnsignedT).wrapping_sub(other as $UnsignedT)
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| other |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u32", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| other |)); M.rust_cast (M.read (| self |)) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u32", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn signum(self) -> Self {
                // Picking the right way to phrase this is complicated
                // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>)
                // so delegate it to `Ord` which is already producing -1/0/+1
                // exactly like we need and can be the place to deal with the complexity.
    
                // FIXME(const-hack): replace with cmp
                if self < 0 { -1 }
                else if self == 0 { 0 }
                else { 1 }
            }
    *)
    Definition signum (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I32 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Integer IntegerKind.I32 (-1) |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.I32 0 |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| Value.Integer IntegerKind.I32 0 |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.I32 1 |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_signum : M.IsAssociatedFunction Self "signum" signum.
    
    (*         pub const fn is_positive(self) -> bool { self > 0 } *)
    Definition is_positive (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.I32 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_positive : M.IsAssociatedFunction Self "is_positive" is_positive.
    
    (*         pub const fn is_negative(self) -> bool { self < 0 } *)
    Definition is_negative (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I32 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_negative : M.IsAssociatedFunction Self "is_negative" is_negative.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i32", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i32", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "i32";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 4 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i32", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i32", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 4 ] [ Ty.path "u8" ];
                Ty.path "i32"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*
            pub const fn min_value() -> Self {
                Self::MIN
            }
    *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*
            pub const fn max_value() -> Self {
                Self::MAX
            }
    *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    (*
                pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                    use self::IntErrorKind::*;
                    use self::ParseIntError as PIE;
    
                    if 2 > radix || radix > 36 {
                        from_str_radix_panic(radix);
                    }
    
                    if src.is_empty() {
                        return Err(PIE { kind: Empty });
                    }
    
                    #[allow(unused_comparisons)]
                    let is_signed_ty = 0 > <$int_ty>::MIN;
    
                    // all valid digits are ascii, so we will just iterate over the utf8 bytes
                    // and cast them to chars. .to_digit() will safely return None for anything
                    // other than a valid ascii digit for the given radix, including the first-byte
                    // of multi-byte sequences
                    let src = src.as_bytes();
    
                    let (is_positive, mut digits) = match src {
                        [b'+' | b'-'] => {
                            return Err(PIE { kind: InvalidDigit });
                        }
                        [b'+', rest @ ..] => (true, rest),
                        [b'-', rest @ ..] if is_signed_ty => (false, rest),
                        _ => (true, src),
                    };
    
                    let mut result = 0;
    
                    macro_rules! unwrap_or_PIE {
                        ($option:expr, $kind:ident) => {
                            match $option {
                                Some(value) => value,
                                None => return Err(PIE { kind: $kind }),
                            }
                        };
                    }
    
                    if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
                        // If the len of the str is short compared to the range of the type
                        // we are parsing into, then we can be certain that an overflow will not occur.
                        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
                        // above is a faster (conservative) approximation of this.
                        //
                        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
                        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
                        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
                        macro_rules! run_unchecked_loop {
                            ($unchecked_additive_op:tt) => {{
                                while let [c, rest @ ..] = digits {
                                    result = result * (radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit);
                                    result = result $unchecked_additive_op (x as $int_ty);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_unchecked_loop!(+)
                        } else {
                            run_unchecked_loop!(-)
                        };
                    } else {
                        macro_rules! run_checked_loop {
                            ($checked_additive_op:ident, $overflow_err:ident) => {{
                                while let [c, rest @ ..] = digits {
                                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
                                    // the compiler can use shifts if `radix` can be expressed as a
                                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
                                    // When the compiler can't use these optimisations,
                                    // the latency of the multiplication can be hidden by issuing it
                                    // before the result is needed to improve performance on
                                    // modern out-of-order CPU as multiplication here is slower
                                    // than the other instructions, we can get the end result faster
                                    // doing multiplication first and let the CPU spends other cycles
                                    // doing other computation and get multiplication result later.
                                    let mul = result.checked_mul(radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit) as $int_ty;
                                    result = unwrap_or_PIE!(mul, $overflow_err);
                                    result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_checked_loop!(checked_add, PosOverflow)
                        } else {
                            run_checked_loop!(checked_sub, NegOverflow)
                        };
                    }
                    Ok(result)
                }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) 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 (|
                                  BinOp.gt (|
                                    Value.Integer IntegerKind.U32 2,
                                    M.read (| radix |)
                                  |),
                                  ltac:(M.monadic
                                    (BinOp.gt (|
                                      M.read (| radix |),
                                      Value.Integer IntegerKind.U32 36
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::num::from_str_radix_panic", [] |),
                                [ M.read (| radix |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                                  [ M.read (| src |) ]
                                |)
                              |)) 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::num::error::ParseIntError"
                                        [
                                          ("kind",
                                            Value.StructTuple
                                              "core::num::error::IntErrorKind::Empty"
                                              [])
                                        ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ is_signed_ty :=
                  M.alloc (|
                    BinOp.gt (|
                      Value.Integer IntegerKind.I32 0,
                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                    |)
                  |) in
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| src |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.match_operator (|
                    src,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                          M.find_or_pattern (|
                            γ1_0,
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 43
                                    |) in
                                  Value.Tuple []));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 45
                                    |) in
                                  Value.Tuple []))
                            ],
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [] =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [
                                                  Value.StructRecord
                                                    "core::num::error::ParseIntError"
                                                    [
                                                      ("kind",
                                                        Value.StructTuple
                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                          [])
                                                    ]
                                                ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 43
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          M.alloc (| Value.Tuple [ Value.Bool true; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 45
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          let γ := is_signed_ty in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Tuple [ Value.Bool false; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (| Value.Tuple [ Value.Bool true; M.read (| src |) ] |)))
                    ]
                  |),
                  [
                    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 is_positive := M.copy (| γ0_0 |) in
                        let digits := M.copy (| γ0_1 |) in
                        let~ result := M.alloc (| Value.Integer IntegerKind.I32 0 |) 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::num::can_not_overflow",
                                            [ Ty.path "i32" ]
                                          |),
                                          [
                                            M.read (| radix |);
                                            M.read (| is_signed_ty |);
                                            M.read (| digits |)
                                          ]
                                        |)
                                      |)) 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 is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.add (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.sub (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ := M.use is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "i32",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "i32",
                                                                      "checked_add",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "i32",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "i32",
                                                                      "checked_sub",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_i32.
  
  Module Impl_i64.
    Definition Self : Ty.t := Ty.path "i64".
    
    (*         pub const MIN: Self = !Self::MAX; *)
    (* Ty.path "i64" *)
    Definition value_MIN : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (| UnOp.not (| M.read (| M.get_constant (| "core::num::MAX" |) |) |) |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = (<$UnsignedT>::MAX >> 1) as Self; *)
    (* Ty.path "i64" *)
    Definition value_MAX : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.rust_cast
              (BinOp.Wrap.shr (|
                M.read (| M.get_constant (| "core::num::MAX" |) |),
                Value.Integer IntegerKind.I32 1
              |))
          |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = <$UnsignedT>::BITS; *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run ltac:(M.monadic (M.get_constant (| "core::num::BITS" |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*         pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "count_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                (self as $UnsignedT).leading_zeros()
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "leading_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                (self as $UnsignedT).trailing_zeros()
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "trailing_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (self as $UnsignedT).leading_ones()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "leading_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (self as $UnsignedT).trailing_ones()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "trailing_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_unsigned(self) -> $UnsignedT {
                self as $UnsignedT
            }
    *)
    Definition cast_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_unsigned :
      M.IsAssociatedFunction Self "cast_unsigned" cast_unsigned.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_left(n) as Self
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u64", "rotate_left", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_right(n) as Self
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u64", "rotate_right", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                (self as $UnsignedT).swap_bytes() as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u64", "swap_bytes", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                (self as $UnsignedT).reverse_bits() as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u64", "reverse_bits", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_add(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "i64" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_unsigned :
      M.IsAssociatedFunction Self "checked_add_unsigned" checked_add_unsigned.
    
    (*
            pub const fn strict_add_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_unsigned :
      M.IsAssociatedFunction Self "strict_add_unsigned" strict_add_unsigned.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_sub(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "i64" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_sub_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub_unsigned :
      M.IsAssociatedFunction Self "checked_sub_unsigned" checked_sub_unsigned.
    
    (*
            pub const fn strict_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub_unsigned :
      M.IsAssociatedFunction Self "strict_sub_unsigned" strict_sub_unsigned.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
            }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "i64" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I64 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.I64 (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "i64" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I64 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I64 (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "i64", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div_euclid(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I64 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.I64 (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "i64" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I64 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I64 (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "i64", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem_euclid(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const unsafe fn unchecked_neg(self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"),
                    (
                        lhs: $SelfT = self,
                    ) => !lhs.overflowing_neg().1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(0, self)
                }
            }
    *)
    Definition unchecked_neg (ε : 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.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.unchecked_neg",
                              []
                            |),
                            [ M.read (| self |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "i64" ] |),
                [ Value.Integer IntegerKind.I64 0; M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_neg :
      M.IsAssociatedFunction Self "unchecked_neg" unchecked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "i64"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i64", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.I64 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "i64"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits.
    
                    // SAFETY:
                    // `Self::BITS-1` is guaranteed to be less than `Self::BITS`
                    unsafe { self.unchecked_shr(Self::BITS - 1) }
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i64", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i64", "unchecked_shr", [] |),
                        [
                          M.read (| self |);
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |)
                        ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_abs(self) -> Option<Self> {
                if self.is_negative() {
                    self.checked_neg()
                } else {
                    Some(self)
                }
            }
    *)
    Definition checked_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i64", "checked_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_abs : M.IsAssociatedFunction Self "checked_abs" checked_abs.
    
    (*
            pub const fn strict_abs(self) -> Self {
                if self.is_negative() {
                    self.strict_neg()
                } else {
                    self
                }
            }
    *)
    Definition strict_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i64", "strict_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_abs : M.IsAssociatedFunction Self "strict_abs" strict_abs.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.I64 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I64 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "i64",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "i64",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I64 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I64 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "i64",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "i64", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn checked_isqrt(self) -> Option<Self> {
                if self < 0 {
                    None
                } else {
                    // SAFETY: Input is nonnegative in this `else` branch.
                    let result = unsafe {
                        crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT
                    };
    
                    // Inform the optimizer what the range of outputs is. If
                    // testing `core` crashes with no panic message and a
                    // `num::int_sqrt::i*` test failed, it's because your edits
                    // caused these assertions to become false.
                    //
                    // SAFETY: Integer square root is a monotonically nondecreasing
                    // function, which means that increasing the input will never
                    // cause the output to decrease. Thus, since the input for
                    // nonnegative signed integers is bounded by
                    // `[0, <$ActualT>::MAX]`, sqrt(n) will be bounded by
                    // `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                    unsafe {
                        // SAFETY: `<$ActualT>::MAX` is nonnegative.
                        const MAX_RESULT: $SelfT = unsafe {
                            crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
                        };
    
                        crate::hint::assert_unchecked(result >= 0);
                        crate::hint::assert_unchecked(result <= MAX_RESULT);
                    }
    
                    Some(result)
                }
            }
    *)
    Definition checked_isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I64 0 |)
                        |)) 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~ result :=
                      M.copy (|
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::num::int_sqrt::i64", [] |),
                              [ M.read (| M.use self |) ]
                            |)
                          |))
                      |) in
                    let~ _ :=
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [ BinOp.ge (| M.read (| result |), Value.Integer IntegerKind.I64 0 |) ]
                          |)
                        |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [
                              BinOp.le (|
                                M.read (| result |),
                                M.read (|
                                  M.get_constant (| "core::num::checked_isqrt::MAX_RESULT" |)
                                |)
                              |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| result |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_isqrt :
      M.IsAssociatedFunction Self "checked_isqrt" checked_isqrt.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "i64" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the upper bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_add_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "checked_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_unsigned :
      M.IsAssociatedFunction Self "saturating_add_unsigned" saturating_add_unsigned.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "i64" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the lower bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_sub_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MIN,
                }
            }
    *)
    Definition saturating_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "checked_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MIN" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub_unsigned :
      M.IsAssociatedFunction Self "saturating_sub_unsigned" saturating_sub_unsigned.
    
    (*
            pub const fn saturating_neg(self) -> Self {
                intrinsics::saturating_sub(0, self)
            }
    *)
    Definition saturating_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "i64" ] |),
            [ Value.Integer IntegerKind.I64 0; M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_neg :
      M.IsAssociatedFunction Self "saturating_neg" saturating_neg.
    
    (*
            pub const fn saturating_abs(self) -> Self {
                if self.is_negative() {
                    self.saturating_neg()
                } else {
                    self
                }
            }
    *)
    Definition saturating_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i64", "saturating_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_abs :
      M.IsAssociatedFunction Self "saturating_abs" saturating_abs.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => if (self < 0) == (rhs < 0) {
                        Self::MAX
                    } else {
                        Self::MIN
                    }
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    BinOp.lt (|
                                      M.read (| self |),
                                      Value.Integer IntegerKind.I64 0
                                    |),
                                    BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I64 0 |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.get_constant (| "core::num::MAX" |)));
                        fun γ => ltac:(M.monadic (M.get_constant (| "core::num::MIN" |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                match self.overflowing_div(rhs) {
                    (result, false) => result,
                    (_result, true) => Self::MAX, // MIN / -1 is the only possible saturating overflow
                }
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool false |) in
                    result));
                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 _result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool true |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None if self < 0 && exp % 2 == 1 => Self::MIN,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    let γ :=
                      M.alloc (|
                        BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I64 0 |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    let γ :=
                      M.alloc (|
                        BinOp.eq (|
                          BinOp.Wrap.rem (| M.read (| exp |), Value.Integer IntegerKind.U32 2 |),
                          Value.Integer IntegerKind.U32 1
                        |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.get_constant (| "core::num::MIN" |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "i64" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_unsigned :
      M.IsAssociatedFunction Self "wrapping_add_unsigned" wrapping_add_unsigned.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "i64" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_sub(rhs as Self)
            }
    *)
    Definition wrapping_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "wrapping_sub", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub_unsigned :
      M.IsAssociatedFunction Self "wrapping_sub_unsigned" wrapping_sub_unsigned.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "i64" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self.overflowing_div(rhs).0
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self.overflowing_div_euclid(rhs).0
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self.overflowing_rem(rhs).0
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self.overflowing_rem_euclid(rhs).0
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "wrapping_sub", [] |),
            [ M.read (| M.use (M.alloc (| Value.Integer IntegerKind.I64 0 |)) |); M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_abs(self) -> Self {
                 if self.is_negative() {
                     self.wrapping_neg()
                 } else {
                     self
                 }
            }
    *)
    Definition wrapping_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i64", "wrapping_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_abs : M.IsAssociatedFunction Self "wrapping_abs" wrapping_abs.
    
    (*
            pub const fn unsigned_abs(self) -> $UnsignedT {
                 self.wrapping_abs() as $UnsignedT
            }
    *)
    Definition unsigned_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "i64", "wrapping_abs", [] |),
              [ M.read (| self |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unsigned_abs : M.IsAssociatedFunction Self "unsigned_abs" unsigned_abs.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I64 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I64 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "i64",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "i64",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "i64", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "i64",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "i64",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "i64" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b != d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i64", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_add(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I64 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_unsigned :
      M.IsAssociatedFunction Self "overflowing_add_unsigned" overflowing_add_unsigned.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "i64" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b != d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i64", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn overflowing_sub_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_sub(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I64 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub_unsigned :
      M.IsAssociatedFunction Self "overflowing_sub_unsigned" overflowing_sub_unsigned.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "i64" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self / rhs, false)
                }
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.I64 (-1)
                                |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self.div_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.I64 (-1)
                                |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self % rhs, false)
                }
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I64 (-1) |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.I64 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self.rem_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I64 (-1) |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.I64 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                if unlikely!(self == Self::MIN) {
                    (Self::MIN, true)
                } else {
                    (-self, false)
                }
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.eq (|
                                M.read (| self |),
                                M.read (| M.get_constant (| "core::num::MIN" |) |)
                              |)
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [ M.read (| M.get_constant (| "core::num::MIN" |) |); Value.Bool true ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple [ UnOp.neg (| M.read (| self |) |); Value.Bool false ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i64", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i64", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_abs(self) -> (Self, bool) {
                (self.wrapping_abs(), self == Self::MIN)
            }
    *)
    Definition overflowing_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i64", "wrapping_abs", [] |),
                [ M.read (| self |) ]
              |);
              BinOp.eq (| M.read (| self |), M.read (| M.get_constant (| "core::num::MIN" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_abs :
      M.IsAssociatedFunction Self "overflowing_abs" overflowing_abs.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0 {
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple [ Value.Integer IntegerKind.I64 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I64 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "i64",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "i64",
                                  "overflowing_mul",
                                  []
                                |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I64 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I64 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                match self.checked_isqrt() {
                    Some(sqrt) => sqrt,
                    None => crate::num::int_sqrt::panic_for_negative_argument(),
                }
            }
    *)
    Definition isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "checked_isqrt", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let sqrt := M.copy (| γ0_0 |) in
                    sqrt));
                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::num::int_sqrt::panic_for_negative_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                let q = self / rhs;
                if self % rhs < 0 {
                    return if rhs > 0 { q - 1 } else { q + 1 }
                }
                q
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ q := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                                  Value.Integer IntegerKind.I64 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_ (|
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.gt (|
                                                    M.read (| rhs |),
                                                    Value.Integer IntegerKind.I64 0
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.alloc (|
                                              BinOp.Wrap.sub (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.I64 1
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              BinOp.Wrap.add (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.I64 1
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                q
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                let r = self % rhs;
                if r < 0 {
                    // Semantically equivalent to `if rhs < 0 { r - rhs } else { r + rhs }`.
                    // If `rhs` is not `Self::MIN`, then `r + abs(rhs)` will not overflow
                    // and is clearly equivalent, because `r` is negative.
                    // Otherwise, `rhs` is `Self::MIN`, then we have
                    // `r.wrapping_add(Self::MIN.wrapping_abs())`, which evaluates
                    // to `r.wrapping_add(Self::MIN)`, which is equivalent to
                    // `r - Self::MIN`, which is what we wanted (and will not overflow
                    // for negative `r`).
                    r.wrapping_add(rhs.wrapping_abs())
                } else {
                    r
                }
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| r |), Value.Integer IntegerKind.I64 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i64", "wrapping_add", [] |),
                        [
                          M.read (| r |);
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "wrapping_abs", [] |),
                            [ M.read (| rhs |) ]
                          |)
                        ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic r)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // If the remainder is non-zero, we need to subtract one if the
                // signs of self and rhs differ, as this means we rounded upwards
                // instead of downwards. We do this branchlessly by creating a mask
                // which is all-ones iff the signs differ, and 0 otherwise. Then by
                // adding this mask (which corresponds to the signed value -1), we
                // get our correction.
                let correction = (self ^ rhs) >> (Self::BITS - 1);
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.shr (|
                  BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                  BinOp.Wrap.sub (|
                    M.read (| M.get_constant (| "core::num::BITS" |) |),
                    Value.Integer IntegerKind.U32 1
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.I64 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // When remainder is non-zero we have a.div_ceil(b) == 1 + a.div_floor(b),
                // so we can re-use the algorithm from div_floor, just adding 1.
                let correction = 1 + ((self ^ rhs) >> (Self::BITS - 1));
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.add (|
                  Value.Integer IntegerKind.I64 1,
                  BinOp.Wrap.shr (|
                    BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                    BinOp.Wrap.sub (|
                      M.read (| M.get_constant (| "core::num::BITS" |) |),
                      Value.Integer IntegerKind.U32 1
                    |)
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.I64 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return self;
                }
    
                let r = self % rhs;
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    self
                } else {
                    self + (rhs - m)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I64 (-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_ (| M.read (| self |) |) |) |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (|
                                        M.read (| r |),
                                        Value.Integer IntegerKind.I64 0
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.I64 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.I64 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.I64 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.I64 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        self));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          BinOp.Wrap.add (|
                            M.read (| self |),
                            BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return Some(self);
                }
    
                let r = try_opt!(self.checked_rem(rhs));
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    // r + rhs cannot overflow because they have opposite signs
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    Some(self)
                } else {
                    // rhs - m cannot overflow because m has the same sign as rhs
                    self.checked_add(rhs - m)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I64 (-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.StructTuple
                                    "core::option::Option::Some"
                                    [ M.read (| self |) ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i64", "checked_rem", [] |),
                          [ M.read (| self |); M.read (| rhs |) ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let x := M.copy (| γ0_0 |) in
                            x));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                                |)
                              |)
                            |)))
                      ]
                    |)
                  |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (|
                                        M.read (| r |),
                                        Value.Integer IntegerKind.I64 0
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.I64 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.I64 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.I64 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.I64 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn midpoint(self, rhs: Self) -> Self {
                const U: $UnsignedT = <$SelfT>::MIN.unsigned_abs();
    
                // Map an $SelfT to an $UnsignedT
                // ex: i8 [-128; 127] to [0; 255]
                const fn map(a: $SelfT) -> $UnsignedT {
                    (a as $UnsignedT) ^ U
                }
    
                // Map an $UnsignedT to an $SelfT
                // ex: u8 [0; 255] to [-128; 127]
                const fn demap(a: $UnsignedT) -> $SelfT {
                    (a ^ U) as $SelfT
                }
    
                demap(<$UnsignedT>::midpoint(map(self), map(rhs)))
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Self, "demap.midpoint", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "midpoint", [] |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| self |) ]
                  |);
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| rhs |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.I64 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i64", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i64", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i64", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else {
                    // Delegate to the unsigned implementation.
                    // The condition makes sure that both casts are exact.
                    (self as $UnsignedT).checked_ilog(base as $UnsignedT)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.I64 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.I64 1 |)))
                          |)
                        |)) 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 (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u64", "checked_ilog", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| base |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                if self <= 0 {
                    None
                } else {
                    // SAFETY: We just checked that this number is positive
                    let log = (Self::BITS - 1) - unsafe { intrinsics::ctlz_nonzero(self) as u32 };
                    Some(log)
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.le (| M.read (| self |), Value.Integer IntegerKind.I64 0 |)
                        |)) 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~ log :=
                      M.alloc (|
                        BinOp.Wrap.sub (|
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |),
                          M.read (|
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_function (|
                                    "core::intrinsics::ctlz_nonzero",
                                    [ Ty.path "i64" ]
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |))
                          |)
                        |)
                      |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| log |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                if self > 0 {
                    Some(int_log10::$ActualT(self as $ActualT))
                } else {
                    None
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.I64 0 |)
                        |)) 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_function (| "core::num::int_log10::i64", [] |),
                            [ M.read (| M.use self |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn abs(self) -> Self {
                // Note that the #[rustc_inherit_overflow_checks] and #[inline]
                // above mean that the overflow semantics of the subtraction
                // depend on the crate we're being called from.
                if self.is_negative() {
                    -self
                } else {
                    self
                }
            }
    *)
    Definition abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i64", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| UnOp.neg (| M.read (| self |) |) |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs : M.IsAssociatedFunction Self "abs" abs.
    
    (*
            pub const fn abs_diff(self, other: Self) -> $UnsignedT {
                if self < other {
                    // Converting a non-negative x from signed to unsigned by using
                    // `x as U` is left unchanged, but a negative x is converted
                    // to value x + 2^N. Thus if `s` and `o` are binary variables
                    // respectively indicating whether `self` and `other` are
                    // negative, we are computing the mathematical value:
                    //
                    //    (other + o*2^N) - (self + s*2^N)    mod  2^N
                    //    other - self + (o-s)*2^N            mod  2^N
                    //    other - self                        mod  2^N
                    //
                    // Finally, taking the mod 2^N of the mathematical value of
                    // `other - self` does not change it as it already is
                    // in the range [0, 2^N).
                    (other as $UnsignedT).wrapping_sub(self as $UnsignedT)
                } else {
                    (self as $UnsignedT).wrapping_sub(other as $UnsignedT)
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| other |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u64", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| other |)); M.rust_cast (M.read (| self |)) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u64", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn signum(self) -> Self {
                // Picking the right way to phrase this is complicated
                // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>)
                // so delegate it to `Ord` which is already producing -1/0/+1
                // exactly like we need and can be the place to deal with the complexity.
    
                // FIXME(const-hack): replace with cmp
                if self < 0 { -1 }
                else if self == 0 { 0 }
                else { 1 }
            }
    *)
    Definition signum (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I64 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Integer IntegerKind.I64 (-1) |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.I64 0 |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| Value.Integer IntegerKind.I64 0 |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.I64 1 |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_signum : M.IsAssociatedFunction Self "signum" signum.
    
    (*         pub const fn is_positive(self) -> bool { self > 0 } *)
    Definition is_positive (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.I64 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_positive : M.IsAssociatedFunction Self "is_positive" is_positive.
    
    (*         pub const fn is_negative(self) -> bool { self < 0 } *)
    Definition is_negative (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I64 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_negative : M.IsAssociatedFunction Self "is_negative" is_negative.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i64", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i64", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "i64";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 8 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i64", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i64", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 8 ] [ Ty.path "u8" ];
                Ty.path "i64"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*
            pub const fn min_value() -> Self {
                Self::MIN
            }
    *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*
            pub const fn max_value() -> Self {
                Self::MAX
            }
    *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    (*
                pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                    use self::IntErrorKind::*;
                    use self::ParseIntError as PIE;
    
                    if 2 > radix || radix > 36 {
                        from_str_radix_panic(radix);
                    }
    
                    if src.is_empty() {
                        return Err(PIE { kind: Empty });
                    }
    
                    #[allow(unused_comparisons)]
                    let is_signed_ty = 0 > <$int_ty>::MIN;
    
                    // all valid digits are ascii, so we will just iterate over the utf8 bytes
                    // and cast them to chars. .to_digit() will safely return None for anything
                    // other than a valid ascii digit for the given radix, including the first-byte
                    // of multi-byte sequences
                    let src = src.as_bytes();
    
                    let (is_positive, mut digits) = match src {
                        [b'+' | b'-'] => {
                            return Err(PIE { kind: InvalidDigit });
                        }
                        [b'+', rest @ ..] => (true, rest),
                        [b'-', rest @ ..] if is_signed_ty => (false, rest),
                        _ => (true, src),
                    };
    
                    let mut result = 0;
    
                    macro_rules! unwrap_or_PIE {
                        ($option:expr, $kind:ident) => {
                            match $option {
                                Some(value) => value,
                                None => return Err(PIE { kind: $kind }),
                            }
                        };
                    }
    
                    if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
                        // If the len of the str is short compared to the range of the type
                        // we are parsing into, then we can be certain that an overflow will not occur.
                        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
                        // above is a faster (conservative) approximation of this.
                        //
                        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
                        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
                        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
                        macro_rules! run_unchecked_loop {
                            ($unchecked_additive_op:tt) => {{
                                while let [c, rest @ ..] = digits {
                                    result = result * (radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit);
                                    result = result $unchecked_additive_op (x as $int_ty);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_unchecked_loop!(+)
                        } else {
                            run_unchecked_loop!(-)
                        };
                    } else {
                        macro_rules! run_checked_loop {
                            ($checked_additive_op:ident, $overflow_err:ident) => {{
                                while let [c, rest @ ..] = digits {
                                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
                                    // the compiler can use shifts if `radix` can be expressed as a
                                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
                                    // When the compiler can't use these optimisations,
                                    // the latency of the multiplication can be hidden by issuing it
                                    // before the result is needed to improve performance on
                                    // modern out-of-order CPU as multiplication here is slower
                                    // than the other instructions, we can get the end result faster
                                    // doing multiplication first and let the CPU spends other cycles
                                    // doing other computation and get multiplication result later.
                                    let mul = result.checked_mul(radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit) as $int_ty;
                                    result = unwrap_or_PIE!(mul, $overflow_err);
                                    result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_checked_loop!(checked_add, PosOverflow)
                        } else {
                            run_checked_loop!(checked_sub, NegOverflow)
                        };
                    }
                    Ok(result)
                }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) 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 (|
                                  BinOp.gt (|
                                    Value.Integer IntegerKind.U32 2,
                                    M.read (| radix |)
                                  |),
                                  ltac:(M.monadic
                                    (BinOp.gt (|
                                      M.read (| radix |),
                                      Value.Integer IntegerKind.U32 36
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::num::from_str_radix_panic", [] |),
                                [ M.read (| radix |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                                  [ M.read (| src |) ]
                                |)
                              |)) 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::num::error::ParseIntError"
                                        [
                                          ("kind",
                                            Value.StructTuple
                                              "core::num::error::IntErrorKind::Empty"
                                              [])
                                        ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ is_signed_ty :=
                  M.alloc (|
                    BinOp.gt (|
                      Value.Integer IntegerKind.I64 0,
                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                    |)
                  |) in
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| src |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.match_operator (|
                    src,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                          M.find_or_pattern (|
                            γ1_0,
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 43
                                    |) in
                                  Value.Tuple []));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 45
                                    |) in
                                  Value.Tuple []))
                            ],
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [] =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [
                                                  Value.StructRecord
                                                    "core::num::error::ParseIntError"
                                                    [
                                                      ("kind",
                                                        Value.StructTuple
                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                          [])
                                                    ]
                                                ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 43
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          M.alloc (| Value.Tuple [ Value.Bool true; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 45
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          let γ := is_signed_ty in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Tuple [ Value.Bool false; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (| Value.Tuple [ Value.Bool true; M.read (| src |) ] |)))
                    ]
                  |),
                  [
                    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 is_positive := M.copy (| γ0_0 |) in
                        let digits := M.copy (| γ0_1 |) in
                        let~ result := M.alloc (| Value.Integer IntegerKind.I64 0 |) 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::num::can_not_overflow",
                                            [ Ty.path "i64" ]
                                          |),
                                          [
                                            M.read (| radix |);
                                            M.read (| is_signed_ty |);
                                            M.read (| digits |)
                                          ]
                                        |)
                                      |)) 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 is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.add (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.sub (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ := M.use is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "i64",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "i64",
                                                                      "checked_add",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "i64",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "i64",
                                                                      "checked_sub",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_i64.
  
  Module Impl_i128.
    Definition Self : Ty.t := Ty.path "i128".
    
    (*         pub const MIN: Self = !Self::MAX; *)
    (* Ty.path "i128" *)
    Definition value_MIN : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (| UnOp.not (| M.read (| M.get_constant (| "core::num::MAX" |) |) |) |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = (<$UnsignedT>::MAX >> 1) as Self; *)
    (* Ty.path "i128" *)
    Definition value_MAX : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.rust_cast
              (BinOp.Wrap.shr (|
                M.read (| M.get_constant (| "core::num::MAX" |) |),
                Value.Integer IntegerKind.I32 1
              |))
          |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = <$UnsignedT>::BITS; *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run ltac:(M.monadic (M.get_constant (| "core::num::BITS" |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*         pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "count_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                (self as $UnsignedT).leading_zeros()
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "leading_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                (self as $UnsignedT).trailing_zeros()
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "trailing_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (self as $UnsignedT).leading_ones()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "leading_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (self as $UnsignedT).trailing_ones()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "trailing_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_unsigned(self) -> $UnsignedT {
                self as $UnsignedT
            }
    *)
    Definition cast_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_unsigned :
      M.IsAssociatedFunction Self "cast_unsigned" cast_unsigned.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_left(n) as Self
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u128", "rotate_left", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_right(n) as Self
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u128", "rotate_right", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                (self as $UnsignedT).swap_bytes() as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u128", "swap_bytes", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                (self as $UnsignedT).reverse_bits() as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "u128", "reverse_bits", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_add(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "i128" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_unsigned :
      M.IsAssociatedFunction Self "checked_add_unsigned" checked_add_unsigned.
    
    (*
            pub const fn strict_add_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_unsigned :
      M.IsAssociatedFunction Self "strict_add_unsigned" strict_add_unsigned.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_sub(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "i128" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_sub_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub_unsigned :
      M.IsAssociatedFunction Self "checked_sub_unsigned" checked_sub_unsigned.
    
    (*
            pub const fn strict_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub_unsigned :
      M.IsAssociatedFunction Self "strict_sub_unsigned" strict_sub_unsigned.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
            }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "i128" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I128 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.I128 (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "i128" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I128 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I128 (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "i128", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div_euclid(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I128 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.I128 (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "i128" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I128 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I128 (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "i128", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem_euclid(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const unsafe fn unchecked_neg(self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"),
                    (
                        lhs: $SelfT = self,
                    ) => !lhs.overflowing_neg().1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(0, self)
                }
            }
    *)
    Definition unchecked_neg (ε : 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.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.unchecked_neg",
                              []
                            |),
                            [ M.read (| self |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "i128" ] |),
                [ Value.Integer IntegerKind.I128 0; M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_neg :
      M.IsAssociatedFunction Self "unchecked_neg" unchecked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "i128"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i128", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.I128 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "i128"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits.
    
                    // SAFETY:
                    // `Self::BITS-1` is guaranteed to be less than `Self::BITS`
                    unsafe { self.unchecked_shr(Self::BITS - 1) }
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i128", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i128", "unchecked_shr", [] |),
                        [
                          M.read (| self |);
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |)
                        ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_abs(self) -> Option<Self> {
                if self.is_negative() {
                    self.checked_neg()
                } else {
                    Some(self)
                }
            }
    *)
    Definition checked_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i128", "checked_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_abs : M.IsAssociatedFunction Self "checked_abs" checked_abs.
    
    (*
            pub const fn strict_abs(self) -> Self {
                if self.is_negative() {
                    self.strict_neg()
                } else {
                    self
                }
            }
    *)
    Definition strict_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i128", "strict_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_abs : M.IsAssociatedFunction Self "strict_abs" strict_abs.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.I128 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I128 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "i128",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "i128",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I128 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I128 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "i128",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "i128", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn checked_isqrt(self) -> Option<Self> {
                if self < 0 {
                    None
                } else {
                    // SAFETY: Input is nonnegative in this `else` branch.
                    let result = unsafe {
                        crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT
                    };
    
                    // Inform the optimizer what the range of outputs is. If
                    // testing `core` crashes with no panic message and a
                    // `num::int_sqrt::i*` test failed, it's because your edits
                    // caused these assertions to become false.
                    //
                    // SAFETY: Integer square root is a monotonically nondecreasing
                    // function, which means that increasing the input will never
                    // cause the output to decrease. Thus, since the input for
                    // nonnegative signed integers is bounded by
                    // `[0, <$ActualT>::MAX]`, sqrt(n) will be bounded by
                    // `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                    unsafe {
                        // SAFETY: `<$ActualT>::MAX` is nonnegative.
                        const MAX_RESULT: $SelfT = unsafe {
                            crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
                        };
    
                        crate::hint::assert_unchecked(result >= 0);
                        crate::hint::assert_unchecked(result <= MAX_RESULT);
                    }
    
                    Some(result)
                }
            }
    *)
    Definition checked_isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I128 0 |)
                        |)) 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~ result :=
                      M.copy (|
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_function (| "core::num::int_sqrt::i128", [] |),
                              [ M.read (| M.use self |) ]
                            |)
                          |))
                      |) in
                    let~ _ :=
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [ BinOp.ge (| M.read (| result |), Value.Integer IntegerKind.I128 0 |) ]
                          |)
                        |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [
                              BinOp.le (|
                                M.read (| result |),
                                M.read (|
                                  M.get_constant (| "core::num::checked_isqrt::MAX_RESULT" |)
                                |)
                              |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| result |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_isqrt :
      M.IsAssociatedFunction Self "checked_isqrt" checked_isqrt.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "i128" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the upper bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_add_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "checked_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_unsigned :
      M.IsAssociatedFunction Self "saturating_add_unsigned" saturating_add_unsigned.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "i128" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the lower bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_sub_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MIN,
                }
            }
    *)
    Definition saturating_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "checked_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MIN" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub_unsigned :
      M.IsAssociatedFunction Self "saturating_sub_unsigned" saturating_sub_unsigned.
    
    (*
            pub const fn saturating_neg(self) -> Self {
                intrinsics::saturating_sub(0, self)
            }
    *)
    Definition saturating_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "i128" ] |),
            [ Value.Integer IntegerKind.I128 0; M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_neg :
      M.IsAssociatedFunction Self "saturating_neg" saturating_neg.
    
    (*
            pub const fn saturating_abs(self) -> Self {
                if self.is_negative() {
                    self.saturating_neg()
                } else {
                    self
                }
            }
    *)
    Definition saturating_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i128", "saturating_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_abs :
      M.IsAssociatedFunction Self "saturating_abs" saturating_abs.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => if (self < 0) == (rhs < 0) {
                        Self::MAX
                    } else {
                        Self::MIN
                    }
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    BinOp.lt (|
                                      M.read (| self |),
                                      Value.Integer IntegerKind.I128 0
                                    |),
                                    BinOp.lt (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I128 0
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.get_constant (| "core::num::MAX" |)));
                        fun γ => ltac:(M.monadic (M.get_constant (| "core::num::MIN" |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                match self.overflowing_div(rhs) {
                    (result, false) => result,
                    (_result, true) => Self::MAX, // MIN / -1 is the only possible saturating overflow
                }
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool false |) in
                    result));
                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 _result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool true |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None if self < 0 && exp % 2 == 1 => Self::MIN,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    let γ :=
                      M.alloc (|
                        BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I128 0 |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    let γ :=
                      M.alloc (|
                        BinOp.eq (|
                          BinOp.Wrap.rem (| M.read (| exp |), Value.Integer IntegerKind.U32 2 |),
                          Value.Integer IntegerKind.U32 1
                        |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.get_constant (| "core::num::MIN" |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "i128" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_unsigned :
      M.IsAssociatedFunction Self "wrapping_add_unsigned" wrapping_add_unsigned.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "i128" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_sub(rhs as Self)
            }
    *)
    Definition wrapping_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "wrapping_sub", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub_unsigned :
      M.IsAssociatedFunction Self "wrapping_sub_unsigned" wrapping_sub_unsigned.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "i128" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self.overflowing_div(rhs).0
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self.overflowing_div_euclid(rhs).0
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self.overflowing_rem(rhs).0
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self.overflowing_rem_euclid(rhs).0
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "wrapping_sub", [] |),
            [ M.read (| M.use (M.alloc (| Value.Integer IntegerKind.I128 0 |)) |); M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_abs(self) -> Self {
                 if self.is_negative() {
                     self.wrapping_neg()
                 } else {
                     self
                 }
            }
    *)
    Definition wrapping_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i128", "wrapping_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_abs : M.IsAssociatedFunction Self "wrapping_abs" wrapping_abs.
    
    (*
            pub const fn unsigned_abs(self) -> $UnsignedT {
                 self.wrapping_abs() as $UnsignedT
            }
    *)
    Definition unsigned_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "i128", "wrapping_abs", [] |),
              [ M.read (| self |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unsigned_abs : M.IsAssociatedFunction Self "unsigned_abs" unsigned_abs.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I128 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I128 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "i128",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "i128",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "i128", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "i128",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "i128",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "i128" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b != d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i128", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_add(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I128 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_unsigned :
      M.IsAssociatedFunction Self "overflowing_add_unsigned" overflowing_add_unsigned.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "i128" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b != d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i128", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn overflowing_sub_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_sub(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I128 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub_unsigned :
      M.IsAssociatedFunction Self "overflowing_sub_unsigned" overflowing_sub_unsigned.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "i128" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self / rhs, false)
                }
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.I128 (-1)
                                |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self.div_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.I128 (-1)
                                |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self % rhs, false)
                }
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I128 (-1) |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.I128 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self.rem_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I128 (-1) |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.I128 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                if unlikely!(self == Self::MIN) {
                    (Self::MIN, true)
                } else {
                    (-self, false)
                }
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.eq (|
                                M.read (| self |),
                                M.read (| M.get_constant (| "core::num::MIN" |) |)
                              |)
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [ M.read (| M.get_constant (| "core::num::MIN" |) |); Value.Bool true ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple [ UnOp.neg (| M.read (| self |) |); Value.Bool false ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i128", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i128", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_abs(self) -> (Self, bool) {
                (self.wrapping_abs(), self == Self::MIN)
            }
    *)
    Definition overflowing_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i128", "wrapping_abs", [] |),
                [ M.read (| self |) ]
              |);
              BinOp.eq (| M.read (| self |), M.read (| M.get_constant (| "core::num::MIN" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_abs :
      M.IsAssociatedFunction Self "overflowing_abs" overflowing_abs.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0 {
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple [ Value.Integer IntegerKind.I128 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I128 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "i128",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "i128",
                                  "overflowing_mul",
                                  []
                                |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.I128 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.I128 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                match self.checked_isqrt() {
                    Some(sqrt) => sqrt,
                    None => crate::num::int_sqrt::panic_for_negative_argument(),
                }
            }
    *)
    Definition isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i128", "checked_isqrt", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let sqrt := M.copy (| γ0_0 |) in
                    sqrt));
                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::num::int_sqrt::panic_for_negative_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                let q = self / rhs;
                if self % rhs < 0 {
                    return if rhs > 0 { q - 1 } else { q + 1 }
                }
                q
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ q := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                                  Value.Integer IntegerKind.I128 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_ (|
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.gt (|
                                                    M.read (| rhs |),
                                                    Value.Integer IntegerKind.I128 0
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.alloc (|
                                              BinOp.Wrap.sub (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.I128 1
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              BinOp.Wrap.add (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.I128 1
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                q
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                let r = self % rhs;
                if r < 0 {
                    // Semantically equivalent to `if rhs < 0 { r - rhs } else { r + rhs }`.
                    // If `rhs` is not `Self::MIN`, then `r + abs(rhs)` will not overflow
                    // and is clearly equivalent, because `r` is negative.
                    // Otherwise, `rhs` is `Self::MIN`, then we have
                    // `r.wrapping_add(Self::MIN.wrapping_abs())`, which evaluates
                    // to `r.wrapping_add(Self::MIN)`, which is equivalent to
                    // `r - Self::MIN`, which is what we wanted (and will not overflow
                    // for negative `r`).
                    r.wrapping_add(rhs.wrapping_abs())
                } else {
                    r
                }
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| r |), Value.Integer IntegerKind.I128 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "i128", "wrapping_add", [] |),
                        [
                          M.read (| r |);
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "wrapping_abs", [] |),
                            [ M.read (| rhs |) ]
                          |)
                        ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic r)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // If the remainder is non-zero, we need to subtract one if the
                // signs of self and rhs differ, as this means we rounded upwards
                // instead of downwards. We do this branchlessly by creating a mask
                // which is all-ones iff the signs differ, and 0 otherwise. Then by
                // adding this mask (which corresponds to the signed value -1), we
                // get our correction.
                let correction = (self ^ rhs) >> (Self::BITS - 1);
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.shr (|
                  BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                  BinOp.Wrap.sub (|
                    M.read (| M.get_constant (| "core::num::BITS" |) |),
                    Value.Integer IntegerKind.U32 1
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.I128 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // When remainder is non-zero we have a.div_ceil(b) == 1 + a.div_floor(b),
                // so we can re-use the algorithm from div_floor, just adding 1.
                let correction = 1 + ((self ^ rhs) >> (Self::BITS - 1));
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.add (|
                  Value.Integer IntegerKind.I128 1,
                  BinOp.Wrap.shr (|
                    BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                    BinOp.Wrap.sub (|
                      M.read (| M.get_constant (| "core::num::BITS" |) |),
                      Value.Integer IntegerKind.U32 1
                    |)
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.I128 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return self;
                }
    
                let r = self % rhs;
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    self
                } else {
                    self + (rhs - m)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I128 (-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_ (| M.read (| self |) |) |) |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (|
                                        M.read (| r |),
                                        Value.Integer IntegerKind.I128 0
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.I128 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.I128 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.I128 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.I128 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        self));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          BinOp.Wrap.add (|
                            M.read (| self |),
                            BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return Some(self);
                }
    
                let r = try_opt!(self.checked_rem(rhs));
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    // r + rhs cannot overflow because they have opposite signs
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    Some(self)
                } else {
                    // rhs - m cannot overflow because m has the same sign as rhs
                    self.checked_add(rhs - m)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.I128 (-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.StructTuple
                                    "core::option::Option::Some"
                                    [ M.read (| self |) ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i128", "checked_rem", [] |),
                          [ M.read (| self |); M.read (| rhs |) ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let x := M.copy (| γ0_0 |) in
                            x));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                                |)
                              |)
                            |)))
                      ]
                    |)
                  |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (|
                                        M.read (| r |),
                                        Value.Integer IntegerKind.I128 0
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.I128 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.I128 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.I128 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.I128 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn midpoint(self, rhs: Self) -> Self {
                const U: $UnsignedT = <$SelfT>::MIN.unsigned_abs();
    
                // Map an $SelfT to an $UnsignedT
                // ex: i8 [-128; 127] to [0; 255]
                const fn map(a: $SelfT) -> $UnsignedT {
                    (a as $UnsignedT) ^ U
                }
    
                // Map an $UnsignedT to an $SelfT
                // ex: u8 [0; 255] to [-128; 127]
                const fn demap(a: $UnsignedT) -> $SelfT {
                    (a ^ U) as $SelfT
                }
    
                demap(<$UnsignedT>::midpoint(map(self), map(rhs)))
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Self, "demap.midpoint", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u128", "midpoint", [] |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| self |) ]
                  |);
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| rhs |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.I128 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i128", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i128", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "i128", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else {
                    // Delegate to the unsigned implementation.
                    // The condition makes sure that both casts are exact.
                    (self as $UnsignedT).checked_ilog(base as $UnsignedT)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.I128 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.I128 1 |)))
                          |)
                        |)) 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 (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u128", "checked_ilog", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| base |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                if self <= 0 {
                    None
                } else {
                    // SAFETY: We just checked that this number is positive
                    let log = (Self::BITS - 1) - unsafe { intrinsics::ctlz_nonzero(self) as u32 };
                    Some(log)
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.le (| M.read (| self |), Value.Integer IntegerKind.I128 0 |)
                        |)) 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~ log :=
                      M.alloc (|
                        BinOp.Wrap.sub (|
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |),
                          M.read (|
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_function (|
                                    "core::intrinsics::ctlz_nonzero",
                                    [ Ty.path "i128" ]
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |))
                          |)
                        |)
                      |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| log |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                if self > 0 {
                    Some(int_log10::$ActualT(self as $ActualT))
                } else {
                    None
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.I128 0 |)
                        |)) 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_function (| "core::num::int_log10::i128", [] |),
                            [ M.read (| M.use self |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn abs(self) -> Self {
                // Note that the #[rustc_inherit_overflow_checks] and #[inline]
                // above mean that the overflow semantics of the subtraction
                // depend on the crate we're being called from.
                if self.is_negative() {
                    -self
                } else {
                    self
                }
            }
    *)
    Definition abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "i128", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| UnOp.neg (| M.read (| self |) |) |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs : M.IsAssociatedFunction Self "abs" abs.
    
    (*
            pub const fn abs_diff(self, other: Self) -> $UnsignedT {
                if self < other {
                    // Converting a non-negative x from signed to unsigned by using
                    // `x as U` is left unchanged, but a negative x is converted
                    // to value x + 2^N. Thus if `s` and `o` are binary variables
                    // respectively indicating whether `self` and `other` are
                    // negative, we are computing the mathematical value:
                    //
                    //    (other + o*2^N) - (self + s*2^N)    mod  2^N
                    //    other - self + (o-s)*2^N            mod  2^N
                    //    other - self                        mod  2^N
                    //
                    // Finally, taking the mod 2^N of the mathematical value of
                    // `other - self` does not change it as it already is
                    // in the range [0, 2^N).
                    (other as $UnsignedT).wrapping_sub(self as $UnsignedT)
                } else {
                    (self as $UnsignedT).wrapping_sub(other as $UnsignedT)
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| other |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u128", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| other |)); M.rust_cast (M.read (| self |)) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u128", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn signum(self) -> Self {
                // Picking the right way to phrase this is complicated
                // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>)
                // so delegate it to `Ord` which is already producing -1/0/+1
                // exactly like we need and can be the place to deal with the complexity.
    
                // FIXME(const-hack): replace with cmp
                if self < 0 { -1 }
                else if self == 0 { 0 }
                else { 1 }
            }
    *)
    Definition signum (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I128 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Integer IntegerKind.I128 (-1) |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.I128 0 |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| Value.Integer IntegerKind.I128 0 |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.I128 1 |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_signum : M.IsAssociatedFunction Self "signum" signum.
    
    (*         pub const fn is_positive(self) -> bool { self > 0 } *)
    Definition is_positive (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.I128 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_positive : M.IsAssociatedFunction Self "is_positive" is_positive.
    
    (*         pub const fn is_negative(self) -> bool { self < 0 } *)
    Definition is_negative (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.I128 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_negative : M.IsAssociatedFunction Self "is_negative" is_negative.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i128", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i128", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "i128";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 16 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i128", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "i128", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 16 ] [ Ty.path "u8" ];
                Ty.path "i128"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*
            pub const fn min_value() -> Self {
                Self::MIN
            }
    *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*
            pub const fn max_value() -> Self {
                Self::MAX
            }
    *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    (*
                pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                    use self::IntErrorKind::*;
                    use self::ParseIntError as PIE;
    
                    if 2 > radix || radix > 36 {
                        from_str_radix_panic(radix);
                    }
    
                    if src.is_empty() {
                        return Err(PIE { kind: Empty });
                    }
    
                    #[allow(unused_comparisons)]
                    let is_signed_ty = 0 > <$int_ty>::MIN;
    
                    // all valid digits are ascii, so we will just iterate over the utf8 bytes
                    // and cast them to chars. .to_digit() will safely return None for anything
                    // other than a valid ascii digit for the given radix, including the first-byte
                    // of multi-byte sequences
                    let src = src.as_bytes();
    
                    let (is_positive, mut digits) = match src {
                        [b'+' | b'-'] => {
                            return Err(PIE { kind: InvalidDigit });
                        }
                        [b'+', rest @ ..] => (true, rest),
                        [b'-', rest @ ..] if is_signed_ty => (false, rest),
                        _ => (true, src),
                    };
    
                    let mut result = 0;
    
                    macro_rules! unwrap_or_PIE {
                        ($option:expr, $kind:ident) => {
                            match $option {
                                Some(value) => value,
                                None => return Err(PIE { kind: $kind }),
                            }
                        };
                    }
    
                    if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
                        // If the len of the str is short compared to the range of the type
                        // we are parsing into, then we can be certain that an overflow will not occur.
                        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
                        // above is a faster (conservative) approximation of this.
                        //
                        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
                        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
                        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
                        macro_rules! run_unchecked_loop {
                            ($unchecked_additive_op:tt) => {{
                                while let [c, rest @ ..] = digits {
                                    result = result * (radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit);
                                    result = result $unchecked_additive_op (x as $int_ty);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_unchecked_loop!(+)
                        } else {
                            run_unchecked_loop!(-)
                        };
                    } else {
                        macro_rules! run_checked_loop {
                            ($checked_additive_op:ident, $overflow_err:ident) => {{
                                while let [c, rest @ ..] = digits {
                                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
                                    // the compiler can use shifts if `radix` can be expressed as a
                                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
                                    // When the compiler can't use these optimisations,
                                    // the latency of the multiplication can be hidden by issuing it
                                    // before the result is needed to improve performance on
                                    // modern out-of-order CPU as multiplication here is slower
                                    // than the other instructions, we can get the end result faster
                                    // doing multiplication first and let the CPU spends other cycles
                                    // doing other computation and get multiplication result later.
                                    let mul = result.checked_mul(radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit) as $int_ty;
                                    result = unwrap_or_PIE!(mul, $overflow_err);
                                    result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_checked_loop!(checked_add, PosOverflow)
                        } else {
                            run_checked_loop!(checked_sub, NegOverflow)
                        };
                    }
                    Ok(result)
                }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) 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 (|
                                  BinOp.gt (|
                                    Value.Integer IntegerKind.U32 2,
                                    M.read (| radix |)
                                  |),
                                  ltac:(M.monadic
                                    (BinOp.gt (|
                                      M.read (| radix |),
                                      Value.Integer IntegerKind.U32 36
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::num::from_str_radix_panic", [] |),
                                [ M.read (| radix |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                                  [ M.read (| src |) ]
                                |)
                              |)) 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::num::error::ParseIntError"
                                        [
                                          ("kind",
                                            Value.StructTuple
                                              "core::num::error::IntErrorKind::Empty"
                                              [])
                                        ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ is_signed_ty :=
                  M.alloc (|
                    BinOp.gt (|
                      Value.Integer IntegerKind.I128 0,
                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                    |)
                  |) in
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| src |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.match_operator (|
                    src,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                          M.find_or_pattern (|
                            γ1_0,
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 43
                                    |) in
                                  Value.Tuple []));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 45
                                    |) in
                                  Value.Tuple []))
                            ],
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [] =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [
                                                  Value.StructRecord
                                                    "core::num::error::ParseIntError"
                                                    [
                                                      ("kind",
                                                        Value.StructTuple
                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                          [])
                                                    ]
                                                ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 43
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          M.alloc (| Value.Tuple [ Value.Bool true; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 45
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          let γ := is_signed_ty in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Tuple [ Value.Bool false; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (| Value.Tuple [ Value.Bool true; M.read (| src |) ] |)))
                    ]
                  |),
                  [
                    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 is_positive := M.copy (| γ0_0 |) in
                        let digits := M.copy (| γ0_1 |) in
                        let~ result := M.alloc (| Value.Integer IntegerKind.I128 0 |) 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::num::can_not_overflow",
                                            [ Ty.path "i128" ]
                                          |),
                                          [
                                            M.read (| radix |);
                                            M.read (| is_signed_ty |);
                                            M.read (| digits |)
                                          ]
                                        |)
                                      |)) 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 is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.add (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.sub (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ := M.use is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "i128",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "i128",
                                                                      "checked_add",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "i128",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "i128",
                                                                      "checked_sub",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_i128.
  
  Module Impl_isize.
    Definition Self : Ty.t := Ty.path "isize".
    
    (*         pub const MIN: Self = !Self::MAX; *)
    (* Ty.path "isize" *)
    Definition value_MIN : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (| UnOp.not (| M.read (| M.get_constant (| "core::num::MAX" |) |) |) |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = (<$UnsignedT>::MAX >> 1) as Self; *)
    (* Ty.path "isize" *)
    Definition value_MAX : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.rust_cast
              (BinOp.Wrap.shr (|
                M.read (| M.get_constant (| "core::num::MAX" |) |),
                Value.Integer IntegerKind.I32 1
              |))
          |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = <$UnsignedT>::BITS; *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run ltac:(M.monadic (M.get_constant (| "core::num::BITS" |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*         pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "count_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                (self as $UnsignedT).leading_zeros()
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "leading_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                (self as $UnsignedT).trailing_zeros()
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "trailing_zeros", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (self as $UnsignedT).leading_ones()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "leading_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (self as $UnsignedT).trailing_ones()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "trailing_ones", [] |),
            [ M.rust_cast (M.read (| self |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_unsigned(self) -> $UnsignedT {
                self as $UnsignedT
            }
    *)
    Definition cast_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_unsigned :
      M.IsAssociatedFunction Self "cast_unsigned" cast_unsigned.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_left(n) as Self
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "usize", "rotate_left", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                (self as $UnsignedT).rotate_right(n) as Self
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "usize", "rotate_right", [] |),
              [ M.rust_cast (M.read (| self |)); M.read (| n |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                (self as $UnsignedT).swap_bytes() as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "usize", "swap_bytes", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                (self as $UnsignedT).reverse_bits() as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "usize", "reverse_bits", [] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_add(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "isize" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_unsigned :
      M.IsAssociatedFunction Self "checked_add_unsigned" checked_add_unsigned.
    
    (*
            pub const fn strict_add_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_add_unsigned(rhs);
                if b { overflow_panic::add() } else { a }
            }
    *)
    Definition strict_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_unsigned :
      M.IsAssociatedFunction Self "strict_add_unsigned" strict_add_unsigned.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_sub(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "isize" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_sub_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub_unsigned :
      M.IsAssociatedFunction Self "checked_sub_unsigned" checked_sub_unsigned.
    
    (*
            pub const fn strict_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                let (a, b) = self.overflowing_sub_unsigned(rhs);
                if b { overflow_panic::sub() } else { a }
            }
    *)
    Definition strict_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub_unsigned :
      M.IsAssociatedFunction Self "strict_sub_unsigned" strict_sub_unsigned.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
            }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "isize" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.Isize 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.Isize (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "isize" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.Isize 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.Isize (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "isize", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_div_euclid(rhs);
                if b { overflow_panic::div() } else { a }
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::div", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) {
                    None
                } else {
                    // SAFETY: div by zero and by INT_MIN have been checked above
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.Isize 0 |),
                                ltac:(M.monadic
                                  (LogicalOp.and (|
                                    BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.eq (|
                                        M.read (| rhs |),
                                        Value.Integer IntegerKind.Isize (-1)
                                      |)))
                                  |)))
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "isize" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              LogicalOp.or (|
                                BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.Isize 0 |),
                                ltac:(M.monadic
                                  (BinOp.bit_and
                                    (BinOp.eq (|
                                      M.read (| self |),
                                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                                    |))
                                    (BinOp.eq (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.Isize (-1)
                                    |))))
                              |)
                            ]
                          |)
                        |)) 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.path "isize", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_rem_euclid(rhs);
                if b { overflow_panic::rem() } else { a }
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::rem", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const unsafe fn unchecked_neg(self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"),
                    (
                        lhs: $SelfT = self,
                    ) => !lhs.overflowing_neg().1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(0, self)
                }
            }
    *)
    Definition unchecked_neg (ε : 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.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.unchecked_neg",
                              []
                            |),
                            [ M.read (| self |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "isize" ] |),
                [ Value.Integer IntegerKind.Isize 0; M.read (| self |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_neg :
      M.IsAssociatedFunction Self "unchecked_neg" unchecked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "isize"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "isize", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.Isize 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "isize"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits.
    
                    // SAFETY:
                    // `Self::BITS-1` is guaranteed to be less than `Self::BITS`
                    unsafe { self.unchecked_shr(Self::BITS - 1) }
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "isize", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "isize", "unchecked_shr", [] |),
                        [
                          M.read (| self |);
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |)
                        ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_abs(self) -> Option<Self> {
                if self.is_negative() {
                    self.checked_neg()
                } else {
                    Some(self)
                }
            }
    *)
    Definition checked_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "isize", "checked_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_abs : M.IsAssociatedFunction Self "checked_abs" checked_abs.
    
    (*
            pub const fn strict_abs(self) -> Self {
                if self.is_negative() {
                    self.strict_neg()
                } else {
                    self
                }
            }
    *)
    Definition strict_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "isize", "strict_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_abs : M.IsAssociatedFunction Self "strict_abs" strict_abs.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.Isize 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.Isize 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "isize",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "isize",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.Isize 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.Isize 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "isize",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "isize", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn checked_isqrt(self) -> Option<Self> {
                if self < 0 {
                    None
                } else {
                    // SAFETY: Input is nonnegative in this `else` branch.
                    let result = unsafe {
                        crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT
                    };
    
                    // Inform the optimizer what the range of outputs is. If
                    // testing `core` crashes with no panic message and a
                    // `num::int_sqrt::i*` test failed, it's because your edits
                    // caused these assertions to become false.
                    //
                    // SAFETY: Integer square root is a monotonically nondecreasing
                    // function, which means that increasing the input will never
                    // cause the output to decrease. Thus, since the input for
                    // nonnegative signed integers is bounded by
                    // `[0, <$ActualT>::MAX]`, sqrt(n) will be bounded by
                    // `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                    unsafe {
                        // SAFETY: `<$ActualT>::MAX` is nonnegative.
                        const MAX_RESULT: $SelfT = unsafe {
                            crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
                        };
    
                        crate::hint::assert_unchecked(result >= 0);
                        crate::hint::assert_unchecked(result <= MAX_RESULT);
                    }
    
                    Some(result)
                }
            }
    *)
    Definition checked_isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.Isize 0 |)
                        |)) 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~ result :=
                      M.alloc (|
                        M.rust_cast
                          (M.call_closure (|
                            M.get_function (| "core::num::int_sqrt::i64", [] |),
                            [ M.rust_cast (M.read (| self |)) ]
                          |))
                      |) in
                    let~ _ :=
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [ BinOp.ge (| M.read (| result |), Value.Integer IntegerKind.Isize 0 |)
                            ]
                          |)
                        |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::hint::assert_unchecked", [] |),
                            [
                              BinOp.le (|
                                M.read (| result |),
                                M.read (|
                                  M.get_constant (| "core::num::checked_isqrt::MAX_RESULT" |)
                                |)
                              |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| result |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_isqrt :
      M.IsAssociatedFunction Self "checked_isqrt" checked_isqrt.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "isize" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the upper bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_add_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "checked_add_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_unsigned :
      M.IsAssociatedFunction Self "saturating_add_unsigned" saturating_add_unsigned.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "isize" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                // Overflow can only happen at the lower bound
                // We cannot use `unwrap_or` here because it is not `const`
                match self.checked_sub_unsigned(rhs) {
                    Some(x) => x,
                    None => Self::MIN,
                }
            }
    *)
    Definition saturating_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "checked_sub_unsigned", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MIN" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub_unsigned :
      M.IsAssociatedFunction Self "saturating_sub_unsigned" saturating_sub_unsigned.
    
    (*
            pub const fn saturating_neg(self) -> Self {
                intrinsics::saturating_sub(0, self)
            }
    *)
    Definition saturating_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "isize" ] |),
            [ Value.Integer IntegerKind.Isize 0; M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_neg :
      M.IsAssociatedFunction Self "saturating_neg" saturating_neg.
    
    (*
            pub const fn saturating_abs(self) -> Self {
                if self.is_negative() {
                    self.saturating_neg()
                } else {
                    self
                }
            }
    *)
    Definition saturating_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "isize", "saturating_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_abs :
      M.IsAssociatedFunction Self "saturating_abs" saturating_abs.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => if (self < 0) == (rhs < 0) {
                        Self::MAX
                    } else {
                        Self::MIN
                    }
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    BinOp.lt (|
                                      M.read (| self |),
                                      Value.Integer IntegerKind.Isize 0
                                    |),
                                    BinOp.lt (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.Isize 0
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.get_constant (| "core::num::MAX" |)));
                        fun γ => ltac:(M.monadic (M.get_constant (| "core::num::MIN" |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                match self.overflowing_div(rhs) {
                    (result, false) => result,
                    (_result, true) => Self::MAX, // MIN / -1 is the only possible saturating overflow
                }
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool false |) in
                    result));
                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 _result := M.copy (| γ0_0 |) in
                    let _ :=
                      M.is_constant_or_break_match (| M.read (| γ0_1 |), Value.Bool true |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None if self < 0 && exp % 2 == 1 => Self::MIN,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    let γ :=
                      M.alloc (|
                        BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.Isize 0 |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    let γ :=
                      M.alloc (|
                        BinOp.eq (|
                          BinOp.Wrap.rem (| M.read (| exp |), Value.Integer IntegerKind.U32 2 |),
                          Value.Integer IntegerKind.U32 1
                        |)
                      |) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.get_constant (| "core::num::MIN" |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "isize" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_unsigned :
      M.IsAssociatedFunction Self "wrapping_add_unsigned" wrapping_add_unsigned.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "isize" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_sub_unsigned(self, rhs: $UnsignedT) -> Self {
                self.wrapping_sub(rhs as Self)
            }
    *)
    Definition wrapping_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "wrapping_sub", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub_unsigned :
      M.IsAssociatedFunction Self "wrapping_sub_unsigned" wrapping_sub_unsigned.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "isize" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self.overflowing_div(rhs).0
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_div", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self.overflowing_div_euclid(rhs).0
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_div_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self.overflowing_rem(rhs).0
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_rem", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self.overflowing_rem_euclid(rhs).0
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.SubPointer.get_tuple_field (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_rem_euclid", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              0
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "wrapping_sub", [] |),
            [
              M.read (| M.use (M.alloc (| Value.Integer IntegerKind.Isize 0 |)) |);
              M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_abs(self) -> Self {
                 if self.is_negative() {
                     self.wrapping_neg()
                 } else {
                     self
                 }
            }
    *)
    Definition wrapping_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "isize", "wrapping_neg", [] |),
                        [ M.read (| self |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_abs : M.IsAssociatedFunction Self "wrapping_abs" wrapping_abs.
    
    (*
            pub const fn unsigned_abs(self) -> $UnsignedT {
                 self.wrapping_abs() as $UnsignedT
            }
    *)
    Definition unsigned_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_associated_function (| Ty.path "isize", "wrapping_abs", [] |),
              [ M.read (| self |) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unsigned_abs : M.IsAssociatedFunction Self "unsigned_abs" unsigned_abs.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.Isize 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.Isize 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "isize",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "isize",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "isize", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "isize",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "isize",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "i64" ] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.rust_cast (M.read (| a |)); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b != d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "isize", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_add(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.Isize 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_unsigned :
      M.IsAssociatedFunction Self "overflowing_add_unsigned" overflowing_add_unsigned.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "i64" ] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.rust_cast (M.read (| a |)); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic.
                // note: no intermediate overflow is required (https://github.com/rust-lang/rust/issues/85532#issuecomment-1032214946).
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b != d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "isize", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [ M.read (| c |); BinOp.ne (| M.read (| b |), M.read (| d |) |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn overflowing_sub_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
                let rhs = rhs as Self;
                let (res, overflowed) = self.overflowing_sub(rhs);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_sub_unsigned (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ rhs := M.alloc (| M.rust_cast (M.read (| rhs |)) |) in
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.Isize 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub_unsigned :
      M.IsAssociatedFunction Self "overflowing_sub_unsigned" overflowing_sub_unsigned.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "i64" ] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.rust_cast (M.read (| a |)); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self / rhs, false)
                }
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.Isize (-1)
                                |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                // Using `&` helps LLVM see that it is the same check made in division.
                if unlikely!((self == Self::MIN) & (rhs == -1)) {
                    (self, true)
                } else {
                    (self.div_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.bit_and
                                (BinOp.eq (|
                                  M.read (| self |),
                                  M.read (| M.get_constant (| "core::num::MIN" |) |)
                                |))
                                (BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.Isize (-1)
                                |))
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Tuple [ M.read (| self |); Value.Bool true ] |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self % rhs, false)
                }
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.Isize (-1) |)
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.Isize 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                if unlikely!(rhs == -1) {
                    (0, self == Self::MIN)
                } else {
                    (self.rem_euclid(rhs), false)
                }
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.Isize (-1) |)
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          Value.Integer IntegerKind.Isize 0;
                          BinOp.eq (|
                            M.read (| self |),
                            M.read (| M.get_constant (| "core::num::MIN" |) |)
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |);
                          Value.Bool false
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                if unlikely!(self == Self::MIN) {
                    (Self::MIN, true)
                } else {
                    (-self, false)
                }
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              BinOp.eq (|
                                M.read (| self |),
                                M.read (| M.get_constant (| "core::num::MIN" |) |)
                              |)
                            ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.Tuple
                        [ M.read (| M.get_constant (| "core::num::MIN" |) |); Value.Bool true ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      Value.Tuple [ UnOp.neg (| M.read (| self |) |); Value.Bool false ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "isize", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "isize", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_abs(self) -> (Self, bool) {
                (self.wrapping_abs(), self == Self::MIN)
            }
    *)
    Definition overflowing_abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "isize", "wrapping_abs", [] |),
                [ M.read (| self |) ]
              |);
              BinOp.eq (| M.read (| self |), M.read (| M.get_constant (| "core::num::MIN" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_abs :
      M.IsAssociatedFunction Self "overflowing_abs" overflowing_abs.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0 {
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple
                                    [ Value.Integer IntegerKind.Isize 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.Isize 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "isize",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "isize",
                                  "overflowing_mul",
                                  []
                                |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.Isize 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.Isize 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                match self.checked_isqrt() {
                    Some(sqrt) => sqrt,
                    None => crate::num::int_sqrt::panic_for_negative_argument(),
                }
            }
    *)
    Definition isqrt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "isize", "checked_isqrt", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let sqrt := M.copy (| γ0_0 |) in
                    sqrt));
                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::num::int_sqrt::panic_for_negative_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                let q = self / rhs;
                if self % rhs < 0 {
                    return if rhs > 0 { q - 1 } else { q + 1 }
                }
                q
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ q := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                                  Value.Integer IntegerKind.Isize 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_ (|
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.gt (|
                                                    M.read (| rhs |),
                                                    Value.Integer IntegerKind.Isize 0
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.alloc (|
                                              BinOp.Wrap.sub (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.Isize 1
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              BinOp.Wrap.add (|
                                                M.read (| q |),
                                                Value.Integer IntegerKind.Isize 1
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                q
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                let r = self % rhs;
                if r < 0 {
                    // Semantically equivalent to `if rhs < 0 { r - rhs } else { r + rhs }`.
                    // If `rhs` is not `Self::MIN`, then `r + abs(rhs)` will not overflow
                    // and is clearly equivalent, because `r` is negative.
                    // Otherwise, `rhs` is `Self::MIN`, then we have
                    // `r.wrapping_add(Self::MIN.wrapping_abs())`, which evaluates
                    // to `r.wrapping_add(Self::MIN)`, which is equivalent to
                    // `r - Self::MIN`, which is what we wanted (and will not overflow
                    // for negative `r`).
                    r.wrapping_add(rhs.wrapping_abs())
                } else {
                    r
                }
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| r |), Value.Integer IntegerKind.Isize 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "isize", "wrapping_add", [] |),
                        [
                          M.read (| r |);
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "wrapping_abs", [] |),
                            [ M.read (| rhs |) ]
                          |)
                        ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic r)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // If the remainder is non-zero, we need to subtract one if the
                // signs of self and rhs differ, as this means we rounded upwards
                // instead of downwards. We do this branchlessly by creating a mask
                // which is all-ones iff the signs differ, and 0 otherwise. Then by
                // adding this mask (which corresponds to the signed value -1), we
                // get our correction.
                let correction = (self ^ rhs) >> (Self::BITS - 1);
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.shr (|
                  BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                  BinOp.Wrap.sub (|
                    M.read (| M.get_constant (| "core::num::BITS" |) |),
                    Value.Integer IntegerKind.U32 1
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.Isize 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
    
                // When remainder is non-zero we have a.div_ceil(b) == 1 + a.div_floor(b),
                // so we can re-use the algorithm from div_floor, just adding 1.
                let correction = 1 + ((self ^ rhs) >> (Self::BITS - 1));
                if r != 0 {
                    d + correction
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ correction :=
              M.alloc (|
                BinOp.Wrap.add (|
                  Value.Integer IntegerKind.Isize 1,
                  BinOp.Wrap.shr (|
                    BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
                    BinOp.Wrap.sub (|
                      M.read (| M.get_constant (| "core::num::BITS" |) |),
                      Value.Integer IntegerKind.U32 1
                    |)
                  |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.ne (| M.read (| r |), Value.Integer IntegerKind.Isize 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| BinOp.Wrap.add (| M.read (| d |), M.read (| correction |) |) |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return self;
                }
    
                let r = self % rhs;
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    self
                } else {
                    self + (rhs - m)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.Isize (-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_ (| M.read (| self |) |) |) |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (|
                                        M.read (| r |),
                                        Value.Integer IntegerKind.Isize 0
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.Isize 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.Isize 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.Isize 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.Isize 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        self));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          BinOp.Wrap.add (|
                            M.read (| self |),
                            BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                // This would otherwise fail when calculating `r` when self == T::MIN.
                if rhs == -1 {
                    return Some(self);
                }
    
                let r = try_opt!(self.checked_rem(rhs));
                let m = if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
                    // r + rhs cannot overflow because they have opposite signs
                    r + rhs
                } else {
                    r
                };
    
                if m == 0 {
                    Some(self)
                } else {
                    // rhs - m cannot overflow because m has the same sign as rhs
                    self.checked_add(rhs - m)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (|
                                  M.read (| rhs |),
                                  Value.Integer IntegerKind.Isize (-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.StructTuple
                                    "core::option::Option::Some"
                                    [ M.read (| self |) ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ r :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "isize", "checked_rem", [] |),
                          [ M.read (| self |); M.read (| rhs |) ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let x := M.copy (| γ0_0 |) in
                            x));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                                |)
                              |)
                            |)))
                      ]
                    |)
                  |) in
                let~ m :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      BinOp.gt (|
                                        M.read (| r |),
                                        Value.Integer IntegerKind.Isize 0
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.lt (|
                                          M.read (| rhs |),
                                          Value.Integer IntegerKind.Isize 0
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (LogicalOp.and (|
                                        BinOp.lt (|
                                          M.read (| r |),
                                          Value.Integer IntegerKind.Isize 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.gt (|
                                            M.read (| rhs |),
                                            Value.Integer IntegerKind.Isize 0
                                          |)))
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| BinOp.Wrap.add (| M.read (| r |), M.read (| rhs |) |) |)));
                        fun γ => ltac:(M.monadic r)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (| M.read (| m |), Value.Integer IntegerKind.Isize 0 |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| m |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn midpoint(self, rhs: Self) -> Self {
                const U: $UnsignedT = <$SelfT>::MIN.unsigned_abs();
    
                // Map an $SelfT to an $UnsignedT
                // ex: i8 [-128; 127] to [0; 255]
                const fn map(a: $SelfT) -> $UnsignedT {
                    (a as $UnsignedT) ^ U
                }
    
                // Map an $UnsignedT to an $SelfT
                // ex: u8 [0; 255] to [-128; 127]
                const fn demap(a: $UnsignedT) -> $SelfT {
                    (a ^ U) as $SelfT
                }
    
                demap(<$UnsignedT>::midpoint(map(self), map(rhs)))
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Self, "demap.midpoint", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "usize", "midpoint", [] |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| self |) ]
                  |);
                  M.call_closure (|
                    M.get_associated_function (| Self, "map.midpoint", [] |),
                    [ M.read (| rhs |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.Isize 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "isize", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "isize", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "isize", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else {
                    // Delegate to the unsigned implementation.
                    // The condition makes sure that both casts are exact.
                    (self as $UnsignedT).checked_ilog(base as $UnsignedT)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.Isize 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.Isize 1 |)))
                          |)
                        |)) 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 (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "usize", "checked_ilog", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| base |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                if self <= 0 {
                    None
                } else {
                    // SAFETY: We just checked that this number is positive
                    let log = (Self::BITS - 1) - unsafe { intrinsics::ctlz_nonzero(self) as u32 };
                    Some(log)
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.le (| M.read (| self |), Value.Integer IntegerKind.Isize 0 |)
                        |)) 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~ log :=
                      M.alloc (|
                        BinOp.Wrap.sub (|
                          BinOp.Wrap.sub (|
                            M.read (| M.get_constant (| "core::num::BITS" |) |),
                            Value.Integer IntegerKind.U32 1
                          |),
                          M.read (|
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_function (|
                                    "core::intrinsics::ctlz_nonzero",
                                    [ Ty.path "isize" ]
                                  |),
                                  [ M.read (| self |) ]
                                |)
                              |))
                          |)
                        |)
                      |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| log |) ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                if self > 0 {
                    Some(int_log10::$ActualT(self as $ActualT))
                } else {
                    None
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.Isize 0 |)
                        |)) 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_function (| "core::num::int_log10::i64", [] |),
                            [ M.rust_cast (M.read (| self |)) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn abs(self) -> Self {
                // Note that the #[rustc_inherit_overflow_checks] and #[inline]
                // above mean that the overflow semantics of the subtraction
                // depend on the crate we're being called from.
                if self.is_negative() {
                    -self
                } else {
                    self
                }
            }
    *)
    Definition abs (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "isize", "is_negative", [] |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| UnOp.neg (| M.read (| self |) |) |)));
                fun γ => ltac:(M.monadic self)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs : M.IsAssociatedFunction Self "abs" abs.
    
    (*
            pub const fn abs_diff(self, other: Self) -> $UnsignedT {
                if self < other {
                    // Converting a non-negative x from signed to unsigned by using
                    // `x as U` is left unchanged, but a negative x is converted
                    // to value x + 2^N. Thus if `s` and `o` are binary variables
                    // respectively indicating whether `self` and `other` are
                    // negative, we are computing the mathematical value:
                    //
                    //    (other + o*2^N) - (self + s*2^N)    mod  2^N
                    //    other - self + (o-s)*2^N            mod  2^N
                    //    other - self                        mod  2^N
                    //
                    // Finally, taking the mod 2^N of the mathematical value of
                    // `other - self` does not change it as it already is
                    // in the range [0, 2^N).
                    (other as $UnsignedT).wrapping_sub(self as $UnsignedT)
                } else {
                    (self as $UnsignedT).wrapping_sub(other as $UnsignedT)
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| other |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "usize", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| other |)); M.rust_cast (M.read (| self |)) ]
                      |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "usize", "wrapping_sub", [] |),
                        [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn signum(self) -> Self {
                // Picking the right way to phrase this is complicated
                // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>)
                // so delegate it to `Ord` which is already producing -1/0/+1
                // exactly like we need and can be the place to deal with the complexity.
    
                // FIXME(const-hack): replace with cmp
                if self < 0 { -1 }
                else if self == 0 { 0 }
                else { 1 }
            }
    *)
    Definition signum (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.Isize 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (| Value.Integer IntegerKind.Isize (-1) |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| self |),
                                    Value.Integer IntegerKind.Isize 0
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| Value.Integer IntegerKind.Isize 0 |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.Isize 1 |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_signum : M.IsAssociatedFunction Self "signum" signum.
    
    (*         pub const fn is_positive(self) -> bool { self > 0 } *)
    Definition is_positive (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.gt (| M.read (| self |), Value.Integer IntegerKind.Isize 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_positive : M.IsAssociatedFunction Self "is_positive" is_positive.
    
    (*         pub const fn is_negative(self) -> bool { self < 0 } *)
    Definition is_negative (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.lt (| M.read (| self |), Value.Integer IntegerKind.Isize 0 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_negative : M.IsAssociatedFunction Self "is_negative" is_negative.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "isize", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "isize", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "isize";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 8 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "isize", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "isize", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 8 ] [ Ty.path "u8" ];
                Ty.path "isize"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*
            pub const fn min_value() -> Self {
                Self::MIN
            }
    *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*
            pub const fn max_value() -> Self {
                Self::MAX
            }
    *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    (*
            pub const fn from_str_radix(src: &str, radix: u32) -> Result<$size, ParseIntError> {
                match <$t>::from_str_radix(src, radix) {
                    Ok(x) => Ok(x as $size),
                    Err(e) => Err(e),
                }
            }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "i64", "from_str_radix", [] |),
                  [ M.read (| src |); M.read (| radix |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (| γ, "core::result::Result::Ok", 0 |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple "core::result::Result::Ok" [ M.rust_cast (M.read (| x |)) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (| γ, "core::result::Result::Err", 0 |) in
                    let e := M.copy (| γ0_0 |) in
                    M.alloc (| Value.StructTuple "core::result::Result::Err" [ M.read (| e |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_isize.
  
  Definition value_ASCII_CASE_MASK : Value.t :=
    M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U8 32 |))).
  
  Module Impl_u8.
    Definition Self : Ty.t := Ty.path "u8".
    
    (*         pub const MIN: Self = 0; *)
    (* Ty.path "u8" *)
    Definition value_MIN : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U8 0 |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = !0; *)
    (* Ty.path "u8" *)
    Definition value_MAX : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| UnOp.not (| Value.Integer IntegerKind.U8 0 |) |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = Self::MAX.count_ones(); *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u8", "count_ones", [] |),
              [ M.read (| M.get_constant (| "core::num::MAX" |) |) ]
            |)
          |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*
            pub const fn count_ones(self) -> u32 {
                return intrinsics::ctpop(self);
            }
    *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctpop", [ Ty.path "u8" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                return intrinsics::ctlz(self as $ActualT);
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz", [ Ty.path "u8" ] |),
                      [ M.read (| M.use self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                return intrinsics::cttz(self);
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::cttz", [ Ty.path "u8" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (!self).leading_zeros()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "leading_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (!self).trailing_zeros()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "trailing_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_signed(self) -> $SignedT {
                self as $SignedT
            }
    *)
    Definition cast_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_signed : M.IsAssociatedFunction Self "cast_signed" cast_signed.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                return intrinsics::rotate_left(self, n);
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_left", [ Ty.path "u8" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                return intrinsics::rotate_right(self, n);
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_right", [ Ty.path "u8" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                intrinsics::bswap(self as $ActualT) as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.use
              (M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::bswap", [ Ty.path "u8" ] |),
                  [ M.read (| M.use self |) ]
                |)
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                intrinsics::bitreverse(self as $ActualT) as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.use
              (M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::bitreverse", [ Ty.path "u8" ] |),
                  [ M.read (| M.use self |) ]
                |)
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                // This used to use `overflowing_add`, but that means it ends up being
                // a `wrapping_add`, losing some optimization opportunities. Notably,
                // phrasing it this way helps `.checked_add(1)` optimize to a check
                // against `MAX` and a `add nuw`.
                // Per <https://github.com/rust-lang/rust/pull/124114#issuecomment-2066173305>,
                // LLVM is happy to re-form the intrinsic later if useful.
    
                if unlikely!(intrinsics::add_with_overflow(self, rhs).1) {
                    None
                } else {
                    // SAFETY: Just checked it doesn't overflow
                    Some(unsafe { intrinsics::unchecked_add(self, rhs) })
                }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              M.read (|
                                M.SubPointer.get_tuple_field (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::intrinsics::add_with_overflow",
                                        [ Ty.path "u8" ]
                                      |),
                                      [ M.read (| self |); M.read (| rhs |) ]
                                    |)
                                  |),
                                  1
                                |)
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_add",
                              [ Ty.path "u8" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "u8" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_signed(self, rhs: $SignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_signed(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_signed :
      M.IsAssociatedFunction Self "checked_add_signed" checked_add_signed.
    
    (*
            pub const fn strict_add_signed(self, rhs: $SignedT) -> Self {
                let (a, b) = self.overflowing_add_signed(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_signed :
      M.IsAssociatedFunction Self "strict_add_signed" strict_add_signed.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                // Per PR#103299, there's no advantage to the `overflowing` intrinsic
                // for *unsigned* subtraction and we just emit the manual check anyway.
                // Thus, rather than using `overflowing_sub` that produces a wrapping
                // subtraction, check it ourself so we can use an unchecked one.
    
                if self < rhs {
                    None
                } else {
                    // SAFETY: just checked this can't overflow
                    Some(unsafe { intrinsics::unchecked_sub(self, rhs) })
                }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| rhs |) |) |)) 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_function (|
                              "core::intrinsics::unchecked_sub",
                              [ Ty.path "u8" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
             }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "u8" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_signed_diff(self, rhs: Self) -> Option<$SignedT> {
                let res = self.wrapping_sub(rhs) as $SignedT;
                let overflow = (self >= rhs) == (res < 0);
    
                if !overflow {
                    Some(res)
                } else {
                    None
                }
            }
    *)
    Definition checked_signed_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ res :=
              M.alloc (|
                M.rust_cast
                  (M.call_closure (|
                    M.get_associated_function (| Ty.path "u8", "wrapping_sub", [] |),
                    [ M.read (| self |); M.read (| rhs |) ]
                  |))
              |) in
            let~ overflow :=
              M.alloc (|
                BinOp.eq (|
                  BinOp.ge (| M.read (| self |), M.read (| rhs |) |),
                  BinOp.lt (| M.read (| res |), Value.Integer IntegerKind.I8 0 |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := M.use (M.alloc (| UnOp.not (| M.read (| overflow |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| res |) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_signed_diff :
      M.IsAssociatedFunction Self "checked_signed_diff" checked_signed_diff.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
             }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "u8" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U8 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "u8" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U8 0 |) ]
                          |)
                        |)) 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.path "u8", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U8 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "u8" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U8 0 |) ]
                          |)
                        |)) 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.path "u8", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.U8 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u8", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u8", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u8", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else if self < base {
                    Some(0)
                } else {
                    // Since base >= self, n >= 1
                    let mut n = 1;
                    let mut r = base;
    
                    // Optimization for 128 bit wide integers.
                    if Self::BITS == 128 {
                        // The following is a correct lower bound for ⌊log(base,self)⌋ because
                        //
                        // log(base,self) = log(2,self) / log(2,base)
                        //                ≥ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1)
                        //
                        // hence
                        //
                        // ⌊log(base,self)⌋ ≥ ⌊ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1) ⌋ .
                        n = self.ilog2() / (base.ilog2() + 1);
                        r = base.pow(n);
                    }
    
                    while r <= self / base {
                        n += 1;
                        r *= base;
                    }
                    Some(n)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.U8 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.U8 1 |)))
                          |)
                        |)) 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 (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| base |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::option::Option::Some"
                                [ Value.Integer IntegerKind.U32 0 ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let~ n := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                            let~ r := M.copy (| base |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            BinOp.eq (|
                                              M.read (| M.get_constant (| "core::num::BITS" |) |),
                                              Value.Integer IntegerKind.U32 128
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          n,
                                          BinOp.Wrap.div (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "u8",
                                                "ilog2",
                                                []
                                              |),
                                              [ M.read (| self |) ]
                                            |),
                                            BinOp.Wrap.add (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u8",
                                                  "ilog2",
                                                  []
                                                |),
                                                [ M.read (| base |) ]
                                              |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          r,
                                          M.call_closure (|
                                            M.get_associated_function (| Ty.path "u8", "pow", [] |),
                                            [ M.read (| base |); M.read (| n |) ]
                                          |)
                                        |) in
                                      M.alloc (| Value.Tuple [] |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ _ :=
                              M.loop (|
                                ltac:(M.monadic
                                  (M.match_operator (|
                                    M.alloc (| Value.Tuple [] |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ :=
                                            M.use
                                              (M.alloc (|
                                                BinOp.le (|
                                                  M.read (| r |),
                                                  BinOp.Wrap.div (|
                                                    M.read (| self |),
                                                    M.read (| base |)
                                                  |)
                                                |)
                                              |)) in
                                          let _ :=
                                            M.is_constant_or_break_match (|
                                              M.read (| γ |),
                                              Value.Bool true
                                            |) in
                                          let~ _ :=
                                            let β := n in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.add (|
                                                M.read (| β |),
                                                Value.Integer IntegerKind.U32 1
                                              |)
                                            |) in
                                          let~ _ :=
                                            let β := r in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.mul (| M.read (| β |), M.read (| base |) |)
                                            |) 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 (|
                              Value.StructTuple "core::option::Option::Some" [ M.read (| n |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog2()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u8" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u8" ],
                              "ilog2",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog10()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u8" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u8" ],
                              "ilog10",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u8", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "u8"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u8", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U8 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u8", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "u8"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u8", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U8 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.U8 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U8 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u8",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u8",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U8 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U8 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "u8",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "u8", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "u8" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_signed(self, rhs: $SignedT) -> Self {
                let (res, overflow) = self.overflowing_add(rhs as Self);
                if overflow == (rhs < 0) {
                    res
                } else if overflow {
                    Self::MAX
                } else {
                    0
                }
            }
    *)
    Definition saturating_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflow := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| overflow |),
                                    BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I8 0 |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            res));
                        fun γ =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ := M.use overflow in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.get_constant (| "core::num::MAX" |)));
                                fun γ =>
                                  ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U8 0 |)))
                              ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_signed :
      M.IsAssociatedFunction Self "saturating_add_signed" saturating_add_signed.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "u8" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                // on unsigned types, there is no overflow in integer division
                self.wrapping_div(rhs)
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "wrapping_div", [] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "u8" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_signed(self, rhs: $SignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_signed :
      M.IsAssociatedFunction Self "wrapping_add_signed" wrapping_add_signed.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "u8" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "u8" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "wrapping_sub", [] |),
            [ M.read (| M.use (M.alloc (| Value.Integer IntegerKind.U8 0 |)) |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U8 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U8 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "u8",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "u8",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "u8", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "u8",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "u8",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "u8" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b || d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u8", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_signed(self, rhs: $SignedT) -> (Self, bool) {
                let (res, overflowed) = self.overflowing_add(rhs as Self);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I8 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_signed :
      M.IsAssociatedFunction Self "overflowing_add_signed" overflowing_add_signed.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "u8" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b || d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u8", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn abs_diff(self, other: Self) -> Self {
                if mem::size_of::<Self>() == 1 {
                    // Trick LLVM into generating the psadbw instruction when SSE2
                    // is available and this function is autovectorized for u8's.
                    (self as i32).wrapping_sub(other as i32).abs() as Self
                } else {
                    if self < other {
                        other - self
                    } else {
                        self - other
                    }
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.eq (|
                            M.call_closure (|
                              M.get_function (| "core::mem::size_of", [ Ty.path "u8" ] |),
                              []
                            |),
                            Value.Integer IntegerKind.Usize 1
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.rust_cast
                        (M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "abs", [] |),
                          [
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "i32", "wrapping_sub", [] |),
                              [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                            |)
                          ]
                        |))
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| other |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              BinOp.Wrap.sub (| M.read (| other |), M.read (| self |) |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (M.alloc (|
                              BinOp.Wrap.sub (| M.read (| self |), M.read (| other |) |)
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "u8" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                ((!self).wrapping_add(1), self != 0)
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u8", "wrapping_add", [] |),
                [ UnOp.not (| M.read (| self |) |); Value.Integer IntegerKind.U8 1 ]
              |);
              BinOp.ne (| M.read (| self |), Value.Integer IntegerKind.U8 0 |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u8", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u8", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0{
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple [ Value.Integer IntegerKind.U8 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U8 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "u8",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "u8", "overflowing_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U8 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U8 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                let result = crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
    
                // Inform the optimizer what the range of outputs is. If testing
                // `core` crashes with no panic message and a `num::int_sqrt::u*`
                // test failed, it's because your edits caused these assertions or
                // the assertions in `fn isqrt` of `nonzero.rs` to become false.
                //
                // SAFETY: Integer square root is a monotonically nondecreasing
                // function, which means that increasing the input will never
                // cause the output to decrease. Thus, since the input for unsigned
                // integers is bounded by `[0, <$ActualT>::MAX]`, sqrt(n) will be
                // bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                unsafe {
                    const MAX_RESULT: $SelfT = crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
                    crate::hint::assert_unchecked(result <= MAX_RESULT);
                }
    
                result
            }
    *)
    Definition isqrt (ε : 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~ result :=
              M.copy (|
                M.use
                  (M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::num::int_sqrt::u8", [] |),
                      [ M.read (| M.use self |) ]
                    |)
                  |))
              |) in
            let~ _ :=
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (| "core::hint::assert_unchecked", [] |),
                    [
                      BinOp.le (|
                        M.read (| result |),
                        M.read (| M.get_constant (| "core::num::isqrt::MAX_RESULT" |) |)
                      |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |) in
            result
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
                if r > 0 {
                    d + 1
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| r |), Value.Integer IntegerKind.U8 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      BinOp.Wrap.add (| M.read (| d |), Value.Integer IntegerKind.U8 1 |)
                    |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                match self % rhs {
                    0 => self,
                    r => self + (rhs - r)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.U8 0
                      |) in
                    self));
                fun γ =>
                  ltac:(M.monadic
                    (let r := M.copy (| γ |) in
                    M.alloc (|
                      BinOp.Wrap.add (|
                        M.read (| self |),
                        BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                match try_opt!(self.checked_rem(rhs)) {
                    0 => Some(self),
                    // rhs - r cannot overflow because r is smaller than rhs
                    r => self.checked_add(rhs - r)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                M.match_operator (|
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u8", "checked_rem", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let x := M.copy (| γ0_0 |) in
                          x));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                              |)
                            |)
                          |)))
                    ]
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let _ :=
                          M.is_constant_or_break_match (|
                            M.read (| γ |),
                            Value.Integer IntegerKind.U8 0
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let r := M.copy (| γ |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u8", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn is_multiple_of(self, rhs: Self) -> bool {
                match rhs {
                    0 => self == 0,
                    _ => self % rhs == 0,
                }
            }
    *)
    Definition is_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              rhs,
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.U8 0
                      |) in
                    M.alloc (|
                      BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.U8 0 |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      BinOp.eq (|
                        BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                        Value.Integer IntegerKind.U8 0
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_multiple_of :
      M.IsAssociatedFunction Self "is_multiple_of" is_multiple_of.
    
    (*
            pub const fn is_power_of_two(self) -> bool {
                self.count_ones() == 1
            }
    *)
    Definition is_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.eq (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u8", "count_ones", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U32 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_power_of_two :
      M.IsAssociatedFunction Self "is_power_of_two" is_power_of_two.
    
    (*
            const fn one_less_than_next_power_of_two(self) -> Self {
                if self <= 1 { return 0; }
    
                let p = self - 1;
                // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros.
                // That means the shift is always in-bounds, and some processors
                // (such as intel pre-haswell) have more efficient ctlz
                // intrinsics when the argument is non-zero.
                let z = unsafe { intrinsics::ctlz_nonzero(p) };
                <$SelfT>::MAX >> z
            }
    *)
    Definition one_less_than_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ 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 (|
                                BinOp.le (| M.read (| self |), Value.Integer IntegerKind.U8 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.Integer IntegerKind.U8 0 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ p :=
                  M.alloc (|
                    BinOp.Wrap.sub (| M.read (| self |), Value.Integer IntegerKind.U8 1 |)
                  |) in
                let~ z :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz_nonzero", [ Ty.path "u8" ] |),
                      [ M.read (| p |) ]
                    |)
                  |) in
                M.alloc (|
                  BinOp.Wrap.shr (|
                    M.read (| M.get_constant (| "core::num::MAX" |) |),
                    M.read (| z |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_one_less_than_next_power_of_two :
      M.IsAssociatedFunction Self "one_less_than_next_power_of_two" one_less_than_next_power_of_two.
    
    (*
            pub const fn next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two() + 1
            }
    *)
    Definition next_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.Wrap.add (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u8", "one_less_than_next_power_of_two", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U8 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_power_of_two :
      M.IsAssociatedFunction Self "next_power_of_two" next_power_of_two.
    
    (*
            pub const fn checked_next_power_of_two(self) -> Option<Self> {
                self.one_less_than_next_power_of_two().checked_add(1)
            }
    *)
    Definition checked_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "checked_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u8", "one_less_than_next_power_of_two", [] |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.U8 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_power_of_two :
      M.IsAssociatedFunction Self "checked_next_power_of_two" checked_next_power_of_two.
    
    (*
            pub const fn wrapping_next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two().wrapping_add(1)
            }
    *)
    Definition wrapping_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "wrapping_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u8", "one_less_than_next_power_of_two", [] |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.U8 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_next_power_of_two :
      M.IsAssociatedFunction Self "wrapping_next_power_of_two" wrapping_next_power_of_two.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u8", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u8", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "u8";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 1 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u8", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u8", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 1 ] [ Ty.path "u8" ];
                Ty.path "u8"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*         pub const fn min_value() -> Self { Self::MIN } *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*         pub const fn max_value() -> Self { Self::MAX } *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    
    (*
            pub const fn widening_mul(self, rhs: Self) -> (Self, Self) {
                // note: longer-term this should be done via an intrinsic,
                //   but for now we can deal without an impl for u128/i128
                // SAFETY: overflow will be contained within the wider types
                let wide = unsafe { (self as $WideT).unchecked_mul(rhs as $WideT) };
                (wide as $SelfT, (wide >> $BITS) as $SelfT)
            }
    *)
    Definition widening_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ wide :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "unchecked_mul", [] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.rust_cast (M.read (| wide |));
                  M.rust_cast
                    (BinOp.Wrap.shr (| M.read (| wide |), Value.Integer IntegerKind.I32 8 |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_widening_mul : M.IsAssociatedFunction Self "widening_mul" widening_mul.
    
    (*
            pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
                // note: longer-term this should be done via an intrinsic,
                //   but for now we can deal without an impl for u128/i128
                // SAFETY: overflow will be contained within the wider types
                let wide = unsafe {
                    (self as $WideT).unchecked_mul(rhs as $WideT).unchecked_add(carry as $WideT)
                };
                (wide as $SelfT, (wide >> $BITS) as $SelfT)
            }
    *)
    Definition carrying_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            let~ wide :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "unchecked_add", [] |),
                  [
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "u16", "unchecked_mul", [] |),
                      [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                    |);
                    M.rust_cast (M.read (| carry |))
                  ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.rust_cast (M.read (| wide |));
                  M.rust_cast
                    (BinOp.Wrap.shr (| M.read (| wide |), Value.Integer IntegerKind.I32 8 |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_mul : M.IsAssociatedFunction Self "carrying_mul" carrying_mul.
    
    (*
            pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
                ((self as $WideT + rhs as $WideT) / 2) as $SelfT
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.rust_cast
            (BinOp.Wrap.div (|
              BinOp.Wrap.add (| M.rust_cast (M.read (| self |)), M.rust_cast (M.read (| rhs |)) |),
              Value.Integer IntegerKind.U16 2
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    
    (*
        pub const fn is_ascii(&self) -> bool {
            *self <= 127
        }
    *)
    Definition is_ascii (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.le (| M.read (| M.read (| self |) |), Value.Integer IntegerKind.U8 127 |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii : M.IsAssociatedFunction Self "is_ascii" is_ascii.
    
    (*
        pub const fn as_ascii(&self) -> Option<ascii::Char> {
            ascii::Char::from_u8( *self)
        }
    *)
    Definition as_ascii (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.path "core::ascii::ascii_char::AsciiChar",
              "from_u8",
              []
            |),
            [ M.read (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_ascii : M.IsAssociatedFunction Self "as_ascii" as_ascii.
    
    (*
        pub const fn to_ascii_uppercase(&self) -> u8 {
            // Toggle the 6th bit if this is a lowercase letter
            *self ^ ((self.is_ascii_lowercase() as u8) * ASCII_CASE_MASK)
        }
    *)
    Definition to_ascii_uppercase (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.bit_xor
            (M.read (| M.read (| self |) |))
            (BinOp.Wrap.mul (|
              M.rust_cast
                (M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "is_ascii_lowercase", [] |),
                  [ M.read (| self |) ]
                |)),
              M.read (| M.get_constant (| "core::num::ASCII_CASE_MASK" |) |)
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ascii_uppercase :
      M.IsAssociatedFunction Self "to_ascii_uppercase" to_ascii_uppercase.
    
    (*
        pub const fn to_ascii_lowercase(&self) -> u8 {
            // Set the 6th bit if this is an uppercase letter
            *self | (self.is_ascii_uppercase() as u8 * ASCII_CASE_MASK)
        }
    *)
    Definition to_ascii_lowercase (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.bit_or
            (M.read (| M.read (| self |) |))
            (BinOp.Wrap.mul (|
              M.rust_cast
                (M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "is_ascii_uppercase", [] |),
                  [ M.read (| self |) ]
                |)),
              M.read (| M.get_constant (| "core::num::ASCII_CASE_MASK" |) |)
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ascii_lowercase :
      M.IsAssociatedFunction Self "to_ascii_lowercase" to_ascii_lowercase.
    
    (*
        pub(crate) const fn ascii_change_case_unchecked(&self) -> u8 {
            *self ^ ASCII_CASE_MASK
        }
    *)
    Definition ascii_change_case_unchecked
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.bit_xor
            (M.read (| M.read (| self |) |))
            (M.read (| M.get_constant (| "core::num::ASCII_CASE_MASK" |) |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ascii_change_case_unchecked :
      M.IsAssociatedFunction Self "ascii_change_case_unchecked" ascii_change_case_unchecked.
    
    (*
        pub const fn eq_ignore_ascii_case(&self, other: &u8) -> bool {
            self.to_ascii_lowercase() == other.to_ascii_lowercase()
        }
    *)
    Definition eq_ignore_ascii_case (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          BinOp.eq (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u8", "to_ascii_lowercase", [] |),
              [ M.read (| self |) ]
            |),
            M.call_closure (|
              M.get_associated_function (| Ty.path "u8", "to_ascii_lowercase", [] |),
              [ M.read (| other |) ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_eq_ignore_ascii_case :
      M.IsAssociatedFunction Self "eq_ignore_ascii_case" eq_ignore_ascii_case.
    
    (*
        pub const fn make_ascii_uppercase(&mut self) {
            *self = self.to_ascii_uppercase();
        }
    *)
    Definition make_ascii_uppercase (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.write (|
                M.read (| self |),
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "to_ascii_uppercase", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_make_ascii_uppercase :
      M.IsAssociatedFunction Self "make_ascii_uppercase" make_ascii_uppercase.
    
    (*
        pub const fn make_ascii_lowercase(&mut self) {
            *self = self.to_ascii_lowercase();
        }
    *)
    Definition make_ascii_lowercase (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.write (|
                M.read (| self |),
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u8", "to_ascii_lowercase", [] |),
                  [ M.read (| self |) ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_make_ascii_lowercase :
      M.IsAssociatedFunction Self "make_ascii_lowercase" make_ascii_lowercase.
    
    (*
        pub const fn is_ascii_alphabetic(&self) -> bool {
            matches!( *self, b'A'..=b'Z' | b'a'..=b'z')
        }
    *)
    Definition is_ascii_alphabetic (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.read (| self |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (M.find_or_pattern (|
                      γ,
                      [
                        fun γ => ltac:(M.monadic (Value.Tuple []));
                        fun γ => ltac:(M.monadic (Value.Tuple []))
                      ],
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [] => ltac:(M.monadic (M.alloc (| Value.Bool true |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_alphabetic :
      M.IsAssociatedFunction Self "is_ascii_alphabetic" is_ascii_alphabetic.
    
    (*
        pub const fn is_ascii_uppercase(&self) -> bool {
            matches!( *self, b'A'..=b'Z')
        }
    *)
    Definition is_ascii_uppercase (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.read (| self |),
              [
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_uppercase :
      M.IsAssociatedFunction Self "is_ascii_uppercase" is_ascii_uppercase.
    
    (*
        pub const fn is_ascii_lowercase(&self) -> bool {
            matches!( *self, b'a'..=b'z')
        }
    *)
    Definition is_ascii_lowercase (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.read (| self |),
              [
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_lowercase :
      M.IsAssociatedFunction Self "is_ascii_lowercase" is_ascii_lowercase.
    
    (*
        pub const fn is_ascii_alphanumeric(&self) -> bool {
            matches!( *self, b'0'..=b'9') | matches!( *self, b'A'..=b'Z') | matches!( *self, b'a'..=b'z')
        }
    *)
    Definition is_ascii_alphanumeric (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.bit_or
            (BinOp.bit_or
              (M.read (|
                M.match_operator (|
                  M.read (| self |),
                  [
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                  ]
                |)
              |))
              (M.read (|
                M.match_operator (|
                  M.read (| self |),
                  [
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                  ]
                |)
              |)))
            (M.read (|
              M.match_operator (|
                M.read (| self |),
                [
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                ]
              |)
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_alphanumeric :
      M.IsAssociatedFunction Self "is_ascii_alphanumeric" is_ascii_alphanumeric.
    
    (*
        pub const fn is_ascii_digit(&self) -> bool {
            matches!( *self, b'0'..=b'9')
        }
    *)
    Definition is_ascii_digit (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.read (| self |),
              [
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_digit :
      M.IsAssociatedFunction Self "is_ascii_digit" is_ascii_digit.
    
    (*
        pub const fn is_ascii_octdigit(&self) -> bool {
            matches!( *self, b'0'..=b'7')
        }
    *)
    Definition is_ascii_octdigit (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.read (| self |),
              [
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_octdigit :
      M.IsAssociatedFunction Self "is_ascii_octdigit" is_ascii_octdigit.
    
    (*
        pub const fn is_ascii_hexdigit(&self) -> bool {
            matches!( *self, b'0'..=b'9') | matches!( *self, b'A'..=b'F') | matches!( *self, b'a'..=b'f')
        }
    *)
    Definition is_ascii_hexdigit (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.bit_or
            (BinOp.bit_or
              (M.read (|
                M.match_operator (|
                  M.read (| self |),
                  [
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                  ]
                |)
              |))
              (M.read (|
                M.match_operator (|
                  M.read (| self |),
                  [
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                  ]
                |)
              |)))
            (M.read (|
              M.match_operator (|
                M.read (| self |),
                [
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                ]
              |)
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_hexdigit :
      M.IsAssociatedFunction Self "is_ascii_hexdigit" is_ascii_hexdigit.
    
    (*
        pub const fn is_ascii_punctuation(&self) -> bool {
            matches!( *self, b'!'..=b'/')
                | matches!( *self, b':'..=b'@')
                | matches!( *self, b'['..=b'`')
                | matches!( *self, b'{'..=b'~')
        }
    *)
    Definition is_ascii_punctuation (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.bit_or
            (BinOp.bit_or
              (BinOp.bit_or
                (M.read (|
                  M.match_operator (|
                    M.read (| self |),
                    [
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                    ]
                  |)
                |))
                (M.read (|
                  M.match_operator (|
                    M.read (| self |),
                    [
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                    ]
                  |)
                |)))
              (M.read (|
                M.match_operator (|
                  M.read (| self |),
                  [
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                  ]
                |)
              |)))
            (M.read (|
              M.match_operator (|
                M.read (| self |),
                [
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                ]
              |)
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_punctuation :
      M.IsAssociatedFunction Self "is_ascii_punctuation" is_ascii_punctuation.
    
    (*
        pub const fn is_ascii_graphic(&self) -> bool {
            matches!( *self, b'!'..=b'~')
        }
    *)
    Definition is_ascii_graphic (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.read (| self |),
              [
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_graphic :
      M.IsAssociatedFunction Self "is_ascii_graphic" is_ascii_graphic.
    
    (*
        pub const fn is_ascii_whitespace(&self) -> bool {
            matches!( *self, b'\t' | b'\n' | b'\x0C' | b'\r' | b' ')
        }
    *)
    Definition is_ascii_whitespace (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.read (| self |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (M.find_or_pattern (|
                      γ,
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let _ :=
                              M.is_constant_or_break_match (|
                                M.read (| γ |),
                                Value.Integer IntegerKind.U8 9
                              |) in
                            Value.Tuple []));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ :=
                              M.is_constant_or_break_match (|
                                M.read (| γ |),
                                Value.Integer IntegerKind.U8 10
                              |) in
                            Value.Tuple []));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ :=
                              M.is_constant_or_break_match (|
                                M.read (| γ |),
                                Value.Integer IntegerKind.U8 12
                              |) in
                            Value.Tuple []));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ :=
                              M.is_constant_or_break_match (|
                                M.read (| γ |),
                                Value.Integer IntegerKind.U8 13
                              |) in
                            Value.Tuple []));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ :=
                              M.is_constant_or_break_match (|
                                M.read (| γ |),
                                Value.Integer IntegerKind.U8 32
                              |) in
                            Value.Tuple []))
                      ],
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [] => ltac:(M.monadic (M.alloc (| Value.Bool true |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_whitespace :
      M.IsAssociatedFunction Self "is_ascii_whitespace" is_ascii_whitespace.
    
    (*
        pub const fn is_ascii_control(&self) -> bool {
            matches!( *self, b'\0'..=b'\x1F' | b'\x7F')
        }
    *)
    Definition is_ascii_control (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.read (| self |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (M.find_or_pattern (|
                      γ,
                      [
                        fun γ => ltac:(M.monadic (Value.Tuple []));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ :=
                              M.is_constant_or_break_match (|
                                M.read (| γ |),
                                Value.Integer IntegerKind.U8 127
                              |) in
                            Value.Tuple []))
                      ],
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [] => ltac:(M.monadic (M.alloc (| Value.Bool true |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_ascii_control :
      M.IsAssociatedFunction Self "is_ascii_control" is_ascii_control.
    
    (*
        pub fn escape_ascii(self) -> ascii::EscapeDefault {
            ascii::escape_default(self)
        }
    *)
    Definition escape_ascii (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (| "core::ascii::escape_default", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_escape_ascii : M.IsAssociatedFunction Self "escape_ascii" escape_ascii.
    
    (*
        pub(crate) const fn is_utf8_char_boundary(self) -> bool {
            // This is bit magic equivalent to: b < 128 || b >= 192
            (self as i8) >= -0x40
        }
    *)
    Definition is_utf8_char_boundary (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.ge (| M.rust_cast (M.read (| self |)), Value.Integer IntegerKind.I8 (-64) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_utf8_char_boundary :
      M.IsAssociatedFunction Self "is_utf8_char_boundary" is_utf8_char_boundary.
    (*
                pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                    use self::IntErrorKind::*;
                    use self::ParseIntError as PIE;
    
                    if 2 > radix || radix > 36 {
                        from_str_radix_panic(radix);
                    }
    
                    if src.is_empty() {
                        return Err(PIE { kind: Empty });
                    }
    
                    #[allow(unused_comparisons)]
                    let is_signed_ty = 0 > <$int_ty>::MIN;
    
                    // all valid digits are ascii, so we will just iterate over the utf8 bytes
                    // and cast them to chars. .to_digit() will safely return None for anything
                    // other than a valid ascii digit for the given radix, including the first-byte
                    // of multi-byte sequences
                    let src = src.as_bytes();
    
                    let (is_positive, mut digits) = match src {
                        [b'+' | b'-'] => {
                            return Err(PIE { kind: InvalidDigit });
                        }
                        [b'+', rest @ ..] => (true, rest),
                        [b'-', rest @ ..] if is_signed_ty => (false, rest),
                        _ => (true, src),
                    };
    
                    let mut result = 0;
    
                    macro_rules! unwrap_or_PIE {
                        ($option:expr, $kind:ident) => {
                            match $option {
                                Some(value) => value,
                                None => return Err(PIE { kind: $kind }),
                            }
                        };
                    }
    
                    if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
                        // If the len of the str is short compared to the range of the type
                        // we are parsing into, then we can be certain that an overflow will not occur.
                        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
                        // above is a faster (conservative) approximation of this.
                        //
                        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
                        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
                        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
                        macro_rules! run_unchecked_loop {
                            ($unchecked_additive_op:tt) => {{
                                while let [c, rest @ ..] = digits {
                                    result = result * (radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit);
                                    result = result $unchecked_additive_op (x as $int_ty);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_unchecked_loop!(+)
                        } else {
                            run_unchecked_loop!(-)
                        };
                    } else {
                        macro_rules! run_checked_loop {
                            ($checked_additive_op:ident, $overflow_err:ident) => {{
                                while let [c, rest @ ..] = digits {
                                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
                                    // the compiler can use shifts if `radix` can be expressed as a
                                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
                                    // When the compiler can't use these optimisations,
                                    // the latency of the multiplication can be hidden by issuing it
                                    // before the result is needed to improve performance on
                                    // modern out-of-order CPU as multiplication here is slower
                                    // than the other instructions, we can get the end result faster
                                    // doing multiplication first and let the CPU spends other cycles
                                    // doing other computation and get multiplication result later.
                                    let mul = result.checked_mul(radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit) as $int_ty;
                                    result = unwrap_or_PIE!(mul, $overflow_err);
                                    result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_checked_loop!(checked_add, PosOverflow)
                        } else {
                            run_checked_loop!(checked_sub, NegOverflow)
                        };
                    }
                    Ok(result)
                }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) 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 (|
                                  BinOp.gt (|
                                    Value.Integer IntegerKind.U32 2,
                                    M.read (| radix |)
                                  |),
                                  ltac:(M.monadic
                                    (BinOp.gt (|
                                      M.read (| radix |),
                                      Value.Integer IntegerKind.U32 36
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::num::from_str_radix_panic", [] |),
                                [ M.read (| radix |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                                  [ M.read (| src |) ]
                                |)
                              |)) 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::num::error::ParseIntError"
                                        [
                                          ("kind",
                                            Value.StructTuple
                                              "core::num::error::IntErrorKind::Empty"
                                              [])
                                        ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ is_signed_ty :=
                  M.alloc (|
                    BinOp.gt (|
                      Value.Integer IntegerKind.U8 0,
                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                    |)
                  |) in
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| src |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.match_operator (|
                    src,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                          M.find_or_pattern (|
                            γ1_0,
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 43
                                    |) in
                                  Value.Tuple []));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 45
                                    |) in
                                  Value.Tuple []))
                            ],
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [] =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [
                                                  Value.StructRecord
                                                    "core::num::error::ParseIntError"
                                                    [
                                                      ("kind",
                                                        Value.StructTuple
                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                          [])
                                                    ]
                                                ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 43
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          M.alloc (| Value.Tuple [ Value.Bool true; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 45
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          let γ := is_signed_ty in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Tuple [ Value.Bool false; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (| Value.Tuple [ Value.Bool true; M.read (| src |) ] |)))
                    ]
                  |),
                  [
                    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 is_positive := M.copy (| γ0_0 |) in
                        let digits := M.copy (| γ0_1 |) in
                        let~ result := M.alloc (| Value.Integer IntegerKind.U8 0 |) 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::num::can_not_overflow",
                                            [ Ty.path "u8" ]
                                          |),
                                          [
                                            M.read (| radix |);
                                            M.read (| is_signed_ty |);
                                            M.read (| digits |)
                                          ]
                                        |)
                                      |)) 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 is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.add (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.sub (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ := M.use is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "u8",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "u8",
                                                                      "checked_add",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "u8",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "u8",
                                                                      "checked_sub",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_u8.
  
  Module Impl_u16.
    Definition Self : Ty.t := Ty.path "u16".
    
    (*         pub const MIN: Self = 0; *)
    (* Ty.path "u16" *)
    Definition value_MIN : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U16 0 |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = !0; *)
    (* Ty.path "u16" *)
    Definition value_MAX : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| UnOp.not (| Value.Integer IntegerKind.U16 0 |) |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = Self::MAX.count_ones(); *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u16", "count_ones", [] |),
              [ M.read (| M.get_constant (| "core::num::MAX" |) |) ]
            |)
          |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*
            pub const fn count_ones(self) -> u32 {
                return intrinsics::ctpop(self);
            }
    *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctpop", [ Ty.path "u16" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                return intrinsics::ctlz(self as $ActualT);
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz", [ Ty.path "u16" ] |),
                      [ M.read (| M.use self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                return intrinsics::cttz(self);
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::cttz", [ Ty.path "u16" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (!self).leading_zeros()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "leading_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (!self).trailing_zeros()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "trailing_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_signed(self) -> $SignedT {
                self as $SignedT
            }
    *)
    Definition cast_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_signed : M.IsAssociatedFunction Self "cast_signed" cast_signed.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                return intrinsics::rotate_left(self, n);
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_left", [ Ty.path "u16" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                return intrinsics::rotate_right(self, n);
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_right", [ Ty.path "u16" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                intrinsics::bswap(self as $ActualT) as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.use
              (M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::bswap", [ Ty.path "u16" ] |),
                  [ M.read (| M.use self |) ]
                |)
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                intrinsics::bitreverse(self as $ActualT) as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.use
              (M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::bitreverse", [ Ty.path "u16" ] |),
                  [ M.read (| M.use self |) ]
                |)
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                // This used to use `overflowing_add`, but that means it ends up being
                // a `wrapping_add`, losing some optimization opportunities. Notably,
                // phrasing it this way helps `.checked_add(1)` optimize to a check
                // against `MAX` and a `add nuw`.
                // Per <https://github.com/rust-lang/rust/pull/124114#issuecomment-2066173305>,
                // LLVM is happy to re-form the intrinsic later if useful.
    
                if unlikely!(intrinsics::add_with_overflow(self, rhs).1) {
                    None
                } else {
                    // SAFETY: Just checked it doesn't overflow
                    Some(unsafe { intrinsics::unchecked_add(self, rhs) })
                }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              M.read (|
                                M.SubPointer.get_tuple_field (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::intrinsics::add_with_overflow",
                                        [ Ty.path "u16" ]
                                      |),
                                      [ M.read (| self |); M.read (| rhs |) ]
                                    |)
                                  |),
                                  1
                                |)
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_add",
                              [ Ty.path "u16" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "u16" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_signed(self, rhs: $SignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_signed(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_signed :
      M.IsAssociatedFunction Self "checked_add_signed" checked_add_signed.
    
    (*
            pub const fn strict_add_signed(self, rhs: $SignedT) -> Self {
                let (a, b) = self.overflowing_add_signed(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_signed :
      M.IsAssociatedFunction Self "strict_add_signed" strict_add_signed.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                // Per PR#103299, there's no advantage to the `overflowing` intrinsic
                // for *unsigned* subtraction and we just emit the manual check anyway.
                // Thus, rather than using `overflowing_sub` that produces a wrapping
                // subtraction, check it ourself so we can use an unchecked one.
    
                if self < rhs {
                    None
                } else {
                    // SAFETY: just checked this can't overflow
                    Some(unsafe { intrinsics::unchecked_sub(self, rhs) })
                }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| rhs |) |) |)) 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_function (|
                              "core::intrinsics::unchecked_sub",
                              [ Ty.path "u16" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
             }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "u16" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_signed_diff(self, rhs: Self) -> Option<$SignedT> {
                let res = self.wrapping_sub(rhs) as $SignedT;
                let overflow = (self >= rhs) == (res < 0);
    
                if !overflow {
                    Some(res)
                } else {
                    None
                }
            }
    *)
    Definition checked_signed_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ res :=
              M.alloc (|
                M.rust_cast
                  (M.call_closure (|
                    M.get_associated_function (| Ty.path "u16", "wrapping_sub", [] |),
                    [ M.read (| self |); M.read (| rhs |) ]
                  |))
              |) in
            let~ overflow :=
              M.alloc (|
                BinOp.eq (|
                  BinOp.ge (| M.read (| self |), M.read (| rhs |) |),
                  BinOp.lt (| M.read (| res |), Value.Integer IntegerKind.I16 0 |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := M.use (M.alloc (| UnOp.not (| M.read (| overflow |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| res |) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_signed_diff :
      M.IsAssociatedFunction Self "checked_signed_diff" checked_signed_diff.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
             }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "u16" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U16 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "u16" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U16 0 |) ]
                          |)
                        |)) 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.path "u16", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U16 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "u16" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U16 0 |) ]
                          |)
                        |)) 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.path "u16", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.U16 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u16", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u16", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u16", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else if self < base {
                    Some(0)
                } else {
                    // Since base >= self, n >= 1
                    let mut n = 1;
                    let mut r = base;
    
                    // Optimization for 128 bit wide integers.
                    if Self::BITS == 128 {
                        // The following is a correct lower bound for ⌊log(base,self)⌋ because
                        //
                        // log(base,self) = log(2,self) / log(2,base)
                        //                ≥ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1)
                        //
                        // hence
                        //
                        // ⌊log(base,self)⌋ ≥ ⌊ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1) ⌋ .
                        n = self.ilog2() / (base.ilog2() + 1);
                        r = base.pow(n);
                    }
    
                    while r <= self / base {
                        n += 1;
                        r *= base;
                    }
                    Some(n)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.U16 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.U16 1 |)))
                          |)
                        |)) 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 (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| base |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::option::Option::Some"
                                [ Value.Integer IntegerKind.U32 0 ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let~ n := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                            let~ r := M.copy (| base |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            BinOp.eq (|
                                              M.read (| M.get_constant (| "core::num::BITS" |) |),
                                              Value.Integer IntegerKind.U32 128
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          n,
                                          BinOp.Wrap.div (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "u16",
                                                "ilog2",
                                                []
                                              |),
                                              [ M.read (| self |) ]
                                            |),
                                            BinOp.Wrap.add (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u16",
                                                  "ilog2",
                                                  []
                                                |),
                                                [ M.read (| base |) ]
                                              |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          r,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "u16",
                                              "pow",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| n |) ]
                                          |)
                                        |) in
                                      M.alloc (| Value.Tuple [] |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ _ :=
                              M.loop (|
                                ltac:(M.monadic
                                  (M.match_operator (|
                                    M.alloc (| Value.Tuple [] |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ :=
                                            M.use
                                              (M.alloc (|
                                                BinOp.le (|
                                                  M.read (| r |),
                                                  BinOp.Wrap.div (|
                                                    M.read (| self |),
                                                    M.read (| base |)
                                                  |)
                                                |)
                                              |)) in
                                          let _ :=
                                            M.is_constant_or_break_match (|
                                              M.read (| γ |),
                                              Value.Bool true
                                            |) in
                                          let~ _ :=
                                            let β := n in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.add (|
                                                M.read (| β |),
                                                Value.Integer IntegerKind.U32 1
                                              |)
                                            |) in
                                          let~ _ :=
                                            let β := r in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.mul (| M.read (| β |), M.read (| base |) |)
                                            |) 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 (|
                              Value.StructTuple "core::option::Option::Some" [ M.read (| n |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog2()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u16" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u16" ],
                              "ilog2",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog10()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u16" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u16" ],
                              "ilog10",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u16", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "u16"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u16", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U16 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u16", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "u16"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u16", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U16 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.U16 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U16 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u16",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u16",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U16 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U16 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "u16",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "u16", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "u16" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_signed(self, rhs: $SignedT) -> Self {
                let (res, overflow) = self.overflowing_add(rhs as Self);
                if overflow == (rhs < 0) {
                    res
                } else if overflow {
                    Self::MAX
                } else {
                    0
                }
            }
    *)
    Definition saturating_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflow := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| overflow |),
                                    BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I16 0 |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            res));
                        fun γ =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ := M.use overflow in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.get_constant (| "core::num::MAX" |)));
                                fun γ =>
                                  ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U16 0 |)))
                              ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_signed :
      M.IsAssociatedFunction Self "saturating_add_signed" saturating_add_signed.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "u16" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                // on unsigned types, there is no overflow in integer division
                self.wrapping_div(rhs)
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "wrapping_div", [] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "u16" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_signed(self, rhs: $SignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_signed :
      M.IsAssociatedFunction Self "wrapping_add_signed" wrapping_add_signed.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "u16" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "u16" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "wrapping_sub", [] |),
            [ M.read (| M.use (M.alloc (| Value.Integer IntegerKind.U16 0 |)) |); M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U16 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U16 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "u16",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "u16",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "u16", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "u16",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "u16",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "u16" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b || d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u16", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_signed(self, rhs: $SignedT) -> (Self, bool) {
                let (res, overflowed) = self.overflowing_add(rhs as Self);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I16 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_signed :
      M.IsAssociatedFunction Self "overflowing_add_signed" overflowing_add_signed.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "u16" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b || d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u16", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u16", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn abs_diff(self, other: Self) -> Self {
                if mem::size_of::<Self>() == 1 {
                    // Trick LLVM into generating the psadbw instruction when SSE2
                    // is available and this function is autovectorized for u8's.
                    (self as i32).wrapping_sub(other as i32).abs() as Self
                } else {
                    if self < other {
                        other - self
                    } else {
                        self - other
                    }
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.eq (|
                            M.call_closure (|
                              M.get_function (| "core::mem::size_of", [ Ty.path "u16" ] |),
                              []
                            |),
                            Value.Integer IntegerKind.Usize 1
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.rust_cast
                        (M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "abs", [] |),
                          [
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "i32", "wrapping_sub", [] |),
                              [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                            |)
                          ]
                        |))
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| other |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              BinOp.Wrap.sub (| M.read (| other |), M.read (| self |) |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (M.alloc (|
                              BinOp.Wrap.sub (| M.read (| self |), M.read (| other |) |)
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "u16" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                ((!self).wrapping_add(1), self != 0)
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u16", "wrapping_add", [] |),
                [ UnOp.not (| M.read (| self |) |); Value.Integer IntegerKind.U16 1 ]
              |);
              BinOp.ne (| M.read (| self |), Value.Integer IntegerKind.U16 0 |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u16", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u16", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0{
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple [ Value.Integer IntegerKind.U16 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U16 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "u16",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "u16",
                                  "overflowing_mul",
                                  []
                                |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U16 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U16 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                let result = crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
    
                // Inform the optimizer what the range of outputs is. If testing
                // `core` crashes with no panic message and a `num::int_sqrt::u*`
                // test failed, it's because your edits caused these assertions or
                // the assertions in `fn isqrt` of `nonzero.rs` to become false.
                //
                // SAFETY: Integer square root is a monotonically nondecreasing
                // function, which means that increasing the input will never
                // cause the output to decrease. Thus, since the input for unsigned
                // integers is bounded by `[0, <$ActualT>::MAX]`, sqrt(n) will be
                // bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                unsafe {
                    const MAX_RESULT: $SelfT = crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
                    crate::hint::assert_unchecked(result <= MAX_RESULT);
                }
    
                result
            }
    *)
    Definition isqrt (ε : 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~ result :=
              M.copy (|
                M.use
                  (M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::num::int_sqrt::u16", [] |),
                      [ M.read (| M.use self |) ]
                    |)
                  |))
              |) in
            let~ _ :=
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (| "core::hint::assert_unchecked", [] |),
                    [
                      BinOp.le (|
                        M.read (| result |),
                        M.read (| M.get_constant (| "core::num::isqrt::MAX_RESULT" |) |)
                      |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |) in
            result
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
                if r > 0 {
                    d + 1
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| r |), Value.Integer IntegerKind.U16 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      BinOp.Wrap.add (| M.read (| d |), Value.Integer IntegerKind.U16 1 |)
                    |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                match self % rhs {
                    0 => self,
                    r => self + (rhs - r)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.U16 0
                      |) in
                    self));
                fun γ =>
                  ltac:(M.monadic
                    (let r := M.copy (| γ |) in
                    M.alloc (|
                      BinOp.Wrap.add (|
                        M.read (| self |),
                        BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                match try_opt!(self.checked_rem(rhs)) {
                    0 => Some(self),
                    // rhs - r cannot overflow because r is smaller than rhs
                    r => self.checked_add(rhs - r)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                M.match_operator (|
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u16", "checked_rem", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let x := M.copy (| γ0_0 |) in
                          x));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                              |)
                            |)
                          |)))
                    ]
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let _ :=
                          M.is_constant_or_break_match (|
                            M.read (| γ |),
                            Value.Integer IntegerKind.U16 0
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let r := M.copy (| γ |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u16", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn is_multiple_of(self, rhs: Self) -> bool {
                match rhs {
                    0 => self == 0,
                    _ => self % rhs == 0,
                }
            }
    *)
    Definition is_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              rhs,
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.U16 0
                      |) in
                    M.alloc (|
                      BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.U16 0 |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      BinOp.eq (|
                        BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                        Value.Integer IntegerKind.U16 0
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_multiple_of :
      M.IsAssociatedFunction Self "is_multiple_of" is_multiple_of.
    
    (*
            pub const fn is_power_of_two(self) -> bool {
                self.count_ones() == 1
            }
    *)
    Definition is_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.eq (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u16", "count_ones", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U32 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_power_of_two :
      M.IsAssociatedFunction Self "is_power_of_two" is_power_of_two.
    
    (*
            const fn one_less_than_next_power_of_two(self) -> Self {
                if self <= 1 { return 0; }
    
                let p = self - 1;
                // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros.
                // That means the shift is always in-bounds, and some processors
                // (such as intel pre-haswell) have more efficient ctlz
                // intrinsics when the argument is non-zero.
                let z = unsafe { intrinsics::ctlz_nonzero(p) };
                <$SelfT>::MAX >> z
            }
    *)
    Definition one_less_than_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ 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 (|
                                BinOp.le (| M.read (| self |), Value.Integer IntegerKind.U16 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.Integer IntegerKind.U16 0 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ p :=
                  M.alloc (|
                    BinOp.Wrap.sub (| M.read (| self |), Value.Integer IntegerKind.U16 1 |)
                  |) in
                let~ z :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz_nonzero", [ Ty.path "u16" ] |),
                      [ M.read (| p |) ]
                    |)
                  |) in
                M.alloc (|
                  BinOp.Wrap.shr (|
                    M.read (| M.get_constant (| "core::num::MAX" |) |),
                    M.read (| z |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_one_less_than_next_power_of_two :
      M.IsAssociatedFunction Self "one_less_than_next_power_of_two" one_less_than_next_power_of_two.
    
    (*
            pub const fn next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two() + 1
            }
    *)
    Definition next_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.Wrap.add (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u16", "one_less_than_next_power_of_two", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U16 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_power_of_two :
      M.IsAssociatedFunction Self "next_power_of_two" next_power_of_two.
    
    (*
            pub const fn checked_next_power_of_two(self) -> Option<Self> {
                self.one_less_than_next_power_of_two().checked_add(1)
            }
    *)
    Definition checked_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "checked_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "u16",
                  "one_less_than_next_power_of_two",
                  []
                |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.U16 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_power_of_two :
      M.IsAssociatedFunction Self "checked_next_power_of_two" checked_next_power_of_two.
    
    (*
            pub const fn wrapping_next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two().wrapping_add(1)
            }
    *)
    Definition wrapping_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "wrapping_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "u16",
                  "one_less_than_next_power_of_two",
                  []
                |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.U16 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_next_power_of_two :
      M.IsAssociatedFunction Self "wrapping_next_power_of_two" wrapping_next_power_of_two.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u16", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u16", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "u16";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 2 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u16", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u16", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 2 ] [ Ty.path "u8" ];
                Ty.path "u16"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*         pub const fn min_value() -> Self { Self::MIN } *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*         pub const fn max_value() -> Self { Self::MAX } *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    
    (*
            pub const fn widening_mul(self, rhs: Self) -> (Self, Self) {
                // note: longer-term this should be done via an intrinsic,
                //   but for now we can deal without an impl for u128/i128
                // SAFETY: overflow will be contained within the wider types
                let wide = unsafe { (self as $WideT).unchecked_mul(rhs as $WideT) };
                (wide as $SelfT, (wide >> $BITS) as $SelfT)
            }
    *)
    Definition widening_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ wide :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "unchecked_mul", [] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.rust_cast (M.read (| wide |));
                  M.rust_cast
                    (BinOp.Wrap.shr (| M.read (| wide |), Value.Integer IntegerKind.I32 16 |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_widening_mul : M.IsAssociatedFunction Self "widening_mul" widening_mul.
    
    (*
            pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
                // note: longer-term this should be done via an intrinsic,
                //   but for now we can deal without an impl for u128/i128
                // SAFETY: overflow will be contained within the wider types
                let wide = unsafe {
                    (self as $WideT).unchecked_mul(rhs as $WideT).unchecked_add(carry as $WideT)
                };
                (wide as $SelfT, (wide >> $BITS) as $SelfT)
            }
    *)
    Definition carrying_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            let~ wide :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "unchecked_add", [] |),
                  [
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "u32", "unchecked_mul", [] |),
                      [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                    |);
                    M.rust_cast (M.read (| carry |))
                  ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.rust_cast (M.read (| wide |));
                  M.rust_cast
                    (BinOp.Wrap.shr (| M.read (| wide |), Value.Integer IntegerKind.I32 16 |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_mul : M.IsAssociatedFunction Self "carrying_mul" carrying_mul.
    
    (*
            pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
                ((self as $WideT + rhs as $WideT) / 2) as $SelfT
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.rust_cast
            (BinOp.Wrap.div (|
              BinOp.Wrap.add (| M.rust_cast (M.read (| self |)), M.rust_cast (M.read (| rhs |)) |),
              Value.Integer IntegerKind.U32 2
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    
    (*
        pub const fn is_utf16_surrogate(self) -> bool {
            matches!(self, 0xD800..=0xDFFF)
        }
    *)
    Definition is_utf16_surrogate (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              self,
              [
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_utf16_surrogate :
      M.IsAssociatedFunction Self "is_utf16_surrogate" is_utf16_surrogate.
    (*
                pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                    use self::IntErrorKind::*;
                    use self::ParseIntError as PIE;
    
                    if 2 > radix || radix > 36 {
                        from_str_radix_panic(radix);
                    }
    
                    if src.is_empty() {
                        return Err(PIE { kind: Empty });
                    }
    
                    #[allow(unused_comparisons)]
                    let is_signed_ty = 0 > <$int_ty>::MIN;
    
                    // all valid digits are ascii, so we will just iterate over the utf8 bytes
                    // and cast them to chars. .to_digit() will safely return None for anything
                    // other than a valid ascii digit for the given radix, including the first-byte
                    // of multi-byte sequences
                    let src = src.as_bytes();
    
                    let (is_positive, mut digits) = match src {
                        [b'+' | b'-'] => {
                            return Err(PIE { kind: InvalidDigit });
                        }
                        [b'+', rest @ ..] => (true, rest),
                        [b'-', rest @ ..] if is_signed_ty => (false, rest),
                        _ => (true, src),
                    };
    
                    let mut result = 0;
    
                    macro_rules! unwrap_or_PIE {
                        ($option:expr, $kind:ident) => {
                            match $option {
                                Some(value) => value,
                                None => return Err(PIE { kind: $kind }),
                            }
                        };
                    }
    
                    if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
                        // If the len of the str is short compared to the range of the type
                        // we are parsing into, then we can be certain that an overflow will not occur.
                        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
                        // above is a faster (conservative) approximation of this.
                        //
                        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
                        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
                        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
                        macro_rules! run_unchecked_loop {
                            ($unchecked_additive_op:tt) => {{
                                while let [c, rest @ ..] = digits {
                                    result = result * (radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit);
                                    result = result $unchecked_additive_op (x as $int_ty);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_unchecked_loop!(+)
                        } else {
                            run_unchecked_loop!(-)
                        };
                    } else {
                        macro_rules! run_checked_loop {
                            ($checked_additive_op:ident, $overflow_err:ident) => {{
                                while let [c, rest @ ..] = digits {
                                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
                                    // the compiler can use shifts if `radix` can be expressed as a
                                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
                                    // When the compiler can't use these optimisations,
                                    // the latency of the multiplication can be hidden by issuing it
                                    // before the result is needed to improve performance on
                                    // modern out-of-order CPU as multiplication here is slower
                                    // than the other instructions, we can get the end result faster
                                    // doing multiplication first and let the CPU spends other cycles
                                    // doing other computation and get multiplication result later.
                                    let mul = result.checked_mul(radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit) as $int_ty;
                                    result = unwrap_or_PIE!(mul, $overflow_err);
                                    result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_checked_loop!(checked_add, PosOverflow)
                        } else {
                            run_checked_loop!(checked_sub, NegOverflow)
                        };
                    }
                    Ok(result)
                }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) 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 (|
                                  BinOp.gt (|
                                    Value.Integer IntegerKind.U32 2,
                                    M.read (| radix |)
                                  |),
                                  ltac:(M.monadic
                                    (BinOp.gt (|
                                      M.read (| radix |),
                                      Value.Integer IntegerKind.U32 36
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::num::from_str_radix_panic", [] |),
                                [ M.read (| radix |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                                  [ M.read (| src |) ]
                                |)
                              |)) 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::num::error::ParseIntError"
                                        [
                                          ("kind",
                                            Value.StructTuple
                                              "core::num::error::IntErrorKind::Empty"
                                              [])
                                        ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ is_signed_ty :=
                  M.alloc (|
                    BinOp.gt (|
                      Value.Integer IntegerKind.U16 0,
                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                    |)
                  |) in
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| src |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.match_operator (|
                    src,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                          M.find_or_pattern (|
                            γ1_0,
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 43
                                    |) in
                                  Value.Tuple []));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 45
                                    |) in
                                  Value.Tuple []))
                            ],
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [] =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [
                                                  Value.StructRecord
                                                    "core::num::error::ParseIntError"
                                                    [
                                                      ("kind",
                                                        Value.StructTuple
                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                          [])
                                                    ]
                                                ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 43
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          M.alloc (| Value.Tuple [ Value.Bool true; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 45
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          let γ := is_signed_ty in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Tuple [ Value.Bool false; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (| Value.Tuple [ Value.Bool true; M.read (| src |) ] |)))
                    ]
                  |),
                  [
                    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 is_positive := M.copy (| γ0_0 |) in
                        let digits := M.copy (| γ0_1 |) in
                        let~ result := M.alloc (| Value.Integer IntegerKind.U16 0 |) 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::num::can_not_overflow",
                                            [ Ty.path "u16" ]
                                          |),
                                          [
                                            M.read (| radix |);
                                            M.read (| is_signed_ty |);
                                            M.read (| digits |)
                                          ]
                                        |)
                                      |)) 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 is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.add (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.sub (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ := M.use is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "u16",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "u16",
                                                                      "checked_add",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "u16",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "u16",
                                                                      "checked_sub",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_u16.
  
  Module Impl_u32.
    Definition Self : Ty.t := Ty.path "u32".
    
    (*         pub const MIN: Self = 0; *)
    (* Ty.path "u32" *)
    Definition value_MIN : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U32 0 |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = !0; *)
    (* Ty.path "u32" *)
    Definition value_MAX : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| UnOp.not (| Value.Integer IntegerKind.U32 0 |) |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = Self::MAX.count_ones(); *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u32", "count_ones", [] |),
              [ M.read (| M.get_constant (| "core::num::MAX" |) |) ]
            |)
          |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*
            pub const fn count_ones(self) -> u32 {
                return intrinsics::ctpop(self);
            }
    *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctpop", [ Ty.path "u32" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                return intrinsics::ctlz(self as $ActualT);
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz", [ Ty.path "u32" ] |),
                      [ M.read (| M.use self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                return intrinsics::cttz(self);
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::cttz", [ Ty.path "u32" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (!self).leading_zeros()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "leading_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (!self).trailing_zeros()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "trailing_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_signed(self) -> $SignedT {
                self as $SignedT
            }
    *)
    Definition cast_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_signed : M.IsAssociatedFunction Self "cast_signed" cast_signed.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                return intrinsics::rotate_left(self, n);
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_left", [ Ty.path "u32" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                return intrinsics::rotate_right(self, n);
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_right", [ Ty.path "u32" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                intrinsics::bswap(self as $ActualT) as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.use
              (M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::bswap", [ Ty.path "u32" ] |),
                  [ M.read (| M.use self |) ]
                |)
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                intrinsics::bitreverse(self as $ActualT) as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.use
              (M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::bitreverse", [ Ty.path "u32" ] |),
                  [ M.read (| M.use self |) ]
                |)
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                // This used to use `overflowing_add`, but that means it ends up being
                // a `wrapping_add`, losing some optimization opportunities. Notably,
                // phrasing it this way helps `.checked_add(1)` optimize to a check
                // against `MAX` and a `add nuw`.
                // Per <https://github.com/rust-lang/rust/pull/124114#issuecomment-2066173305>,
                // LLVM is happy to re-form the intrinsic later if useful.
    
                if unlikely!(intrinsics::add_with_overflow(self, rhs).1) {
                    None
                } else {
                    // SAFETY: Just checked it doesn't overflow
                    Some(unsafe { intrinsics::unchecked_add(self, rhs) })
                }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              M.read (|
                                M.SubPointer.get_tuple_field (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::intrinsics::add_with_overflow",
                                        [ Ty.path "u32" ]
                                      |),
                                      [ M.read (| self |); M.read (| rhs |) ]
                                    |)
                                  |),
                                  1
                                |)
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_add",
                              [ Ty.path "u32" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "u32" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_signed(self, rhs: $SignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_signed(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_signed :
      M.IsAssociatedFunction Self "checked_add_signed" checked_add_signed.
    
    (*
            pub const fn strict_add_signed(self, rhs: $SignedT) -> Self {
                let (a, b) = self.overflowing_add_signed(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_signed :
      M.IsAssociatedFunction Self "strict_add_signed" strict_add_signed.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                // Per PR#103299, there's no advantage to the `overflowing` intrinsic
                // for *unsigned* subtraction and we just emit the manual check anyway.
                // Thus, rather than using `overflowing_sub` that produces a wrapping
                // subtraction, check it ourself so we can use an unchecked one.
    
                if self < rhs {
                    None
                } else {
                    // SAFETY: just checked this can't overflow
                    Some(unsafe { intrinsics::unchecked_sub(self, rhs) })
                }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| rhs |) |) |)) 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_function (|
                              "core::intrinsics::unchecked_sub",
                              [ Ty.path "u32" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
             }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "u32" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_signed_diff(self, rhs: Self) -> Option<$SignedT> {
                let res = self.wrapping_sub(rhs) as $SignedT;
                let overflow = (self >= rhs) == (res < 0);
    
                if !overflow {
                    Some(res)
                } else {
                    None
                }
            }
    *)
    Definition checked_signed_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ res :=
              M.alloc (|
                M.rust_cast
                  (M.call_closure (|
                    M.get_associated_function (| Ty.path "u32", "wrapping_sub", [] |),
                    [ M.read (| self |); M.read (| rhs |) ]
                  |))
              |) in
            let~ overflow :=
              M.alloc (|
                BinOp.eq (|
                  BinOp.ge (| M.read (| self |), M.read (| rhs |) |),
                  BinOp.lt (| M.read (| res |), Value.Integer IntegerKind.I32 0 |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := M.use (M.alloc (| UnOp.not (| M.read (| overflow |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| res |) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_signed_diff :
      M.IsAssociatedFunction Self "checked_signed_diff" checked_signed_diff.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
             }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "u32" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U32 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "u32" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U32 0 |) ]
                          |)
                        |)) 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.path "u32", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U32 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "u32" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U32 0 |) ]
                          |)
                        |)) 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.path "u32", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.U32 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u32", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u32", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u32", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else if self < base {
                    Some(0)
                } else {
                    // Since base >= self, n >= 1
                    let mut n = 1;
                    let mut r = base;
    
                    // Optimization for 128 bit wide integers.
                    if Self::BITS == 128 {
                        // The following is a correct lower bound for ⌊log(base,self)⌋ because
                        //
                        // log(base,self) = log(2,self) / log(2,base)
                        //                ≥ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1)
                        //
                        // hence
                        //
                        // ⌊log(base,self)⌋ ≥ ⌊ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1) ⌋ .
                        n = self.ilog2() / (base.ilog2() + 1);
                        r = base.pow(n);
                    }
    
                    while r <= self / base {
                        n += 1;
                        r *= base;
                    }
                    Some(n)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.U32 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.U32 1 |)))
                          |)
                        |)) 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 (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| base |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::option::Option::Some"
                                [ Value.Integer IntegerKind.U32 0 ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let~ n := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                            let~ r := M.copy (| base |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            BinOp.eq (|
                                              M.read (| M.get_constant (| "core::num::BITS" |) |),
                                              Value.Integer IntegerKind.U32 128
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          n,
                                          BinOp.Wrap.div (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "u32",
                                                "ilog2",
                                                []
                                              |),
                                              [ M.read (| self |) ]
                                            |),
                                            BinOp.Wrap.add (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u32",
                                                  "ilog2",
                                                  []
                                                |),
                                                [ M.read (| base |) ]
                                              |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          r,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "u32",
                                              "pow",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| n |) ]
                                          |)
                                        |) in
                                      M.alloc (| Value.Tuple [] |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ _ :=
                              M.loop (|
                                ltac:(M.monadic
                                  (M.match_operator (|
                                    M.alloc (| Value.Tuple [] |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ :=
                                            M.use
                                              (M.alloc (|
                                                BinOp.le (|
                                                  M.read (| r |),
                                                  BinOp.Wrap.div (|
                                                    M.read (| self |),
                                                    M.read (| base |)
                                                  |)
                                                |)
                                              |)) in
                                          let _ :=
                                            M.is_constant_or_break_match (|
                                              M.read (| γ |),
                                              Value.Bool true
                                            |) in
                                          let~ _ :=
                                            let β := n in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.add (|
                                                M.read (| β |),
                                                Value.Integer IntegerKind.U32 1
                                              |)
                                            |) in
                                          let~ _ :=
                                            let β := r in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.mul (| M.read (| β |), M.read (| base |) |)
                                            |) 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 (|
                              Value.StructTuple "core::option::Option::Some" [ M.read (| n |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog2()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u32" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u32" ],
                              "ilog2",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog10()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u32" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u32" ],
                              "ilog10",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u32", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "u32"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u32", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U32 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u32", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "u32"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u32", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U32 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.U32 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u32",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u32",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U32 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "u32",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "u32", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "u32" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_signed(self, rhs: $SignedT) -> Self {
                let (res, overflow) = self.overflowing_add(rhs as Self);
                if overflow == (rhs < 0) {
                    res
                } else if overflow {
                    Self::MAX
                } else {
                    0
                }
            }
    *)
    Definition saturating_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflow := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| overflow |),
                                    BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I32 0 |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            res));
                        fun γ =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ := M.use overflow in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.get_constant (| "core::num::MAX" |)));
                                fun γ =>
                                  ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U32 0 |)))
                              ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_signed :
      M.IsAssociatedFunction Self "saturating_add_signed" saturating_add_signed.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "u32" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                // on unsigned types, there is no overflow in integer division
                self.wrapping_div(rhs)
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "wrapping_div", [] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "u32" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_signed(self, rhs: $SignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_signed :
      M.IsAssociatedFunction Self "wrapping_add_signed" wrapping_add_signed.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "u32" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "u32" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "wrapping_sub", [] |),
            [ M.read (| M.use (M.alloc (| Value.Integer IntegerKind.U32 0 |)) |); M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U32 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "u32",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "u32",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "u32", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "u32",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "u32",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "u32" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b || d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u32", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_signed(self, rhs: $SignedT) -> (Self, bool) {
                let (res, overflowed) = self.overflowing_add(rhs as Self);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I32 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_signed :
      M.IsAssociatedFunction Self "overflowing_add_signed" overflowing_add_signed.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "u32" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b || d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u32", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u32", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn abs_diff(self, other: Self) -> Self {
                if mem::size_of::<Self>() == 1 {
                    // Trick LLVM into generating the psadbw instruction when SSE2
                    // is available and this function is autovectorized for u8's.
                    (self as i32).wrapping_sub(other as i32).abs() as Self
                } else {
                    if self < other {
                        other - self
                    } else {
                        self - other
                    }
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.eq (|
                            M.call_closure (|
                              M.get_function (| "core::mem::size_of", [ Ty.path "u32" ] |),
                              []
                            |),
                            Value.Integer IntegerKind.Usize 1
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.rust_cast
                        (M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "abs", [] |),
                          [
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "i32", "wrapping_sub", [] |),
                              [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                            |)
                          ]
                        |))
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| other |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              BinOp.Wrap.sub (| M.read (| other |), M.read (| self |) |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (M.alloc (|
                              BinOp.Wrap.sub (| M.read (| self |), M.read (| other |) |)
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "u32" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                ((!self).wrapping_add(1), self != 0)
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u32", "wrapping_add", [] |),
                [ UnOp.not (| M.read (| self |) |); Value.Integer IntegerKind.U32 1 ]
              |);
              BinOp.ne (| M.read (| self |), Value.Integer IntegerKind.U32 0 |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u32", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u32", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0{
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple [ Value.Integer IntegerKind.U32 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "u32",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "u32",
                                  "overflowing_mul",
                                  []
                                |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U32 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                let result = crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
    
                // Inform the optimizer what the range of outputs is. If testing
                // `core` crashes with no panic message and a `num::int_sqrt::u*`
                // test failed, it's because your edits caused these assertions or
                // the assertions in `fn isqrt` of `nonzero.rs` to become false.
                //
                // SAFETY: Integer square root is a monotonically nondecreasing
                // function, which means that increasing the input will never
                // cause the output to decrease. Thus, since the input for unsigned
                // integers is bounded by `[0, <$ActualT>::MAX]`, sqrt(n) will be
                // bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                unsafe {
                    const MAX_RESULT: $SelfT = crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
                    crate::hint::assert_unchecked(result <= MAX_RESULT);
                }
    
                result
            }
    *)
    Definition isqrt (ε : 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~ result :=
              M.copy (|
                M.use
                  (M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::num::int_sqrt::u32", [] |),
                      [ M.read (| M.use self |) ]
                    |)
                  |))
              |) in
            let~ _ :=
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (| "core::hint::assert_unchecked", [] |),
                    [
                      BinOp.le (|
                        M.read (| result |),
                        M.read (| M.get_constant (| "core::num::isqrt::MAX_RESULT" |) |)
                      |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |) in
            result
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
                if r > 0 {
                    d + 1
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| r |), Value.Integer IntegerKind.U32 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      BinOp.Wrap.add (| M.read (| d |), Value.Integer IntegerKind.U32 1 |)
                    |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                match self % rhs {
                    0 => self,
                    r => self + (rhs - r)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.U32 0
                      |) in
                    self));
                fun γ =>
                  ltac:(M.monadic
                    (let r := M.copy (| γ |) in
                    M.alloc (|
                      BinOp.Wrap.add (|
                        M.read (| self |),
                        BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                match try_opt!(self.checked_rem(rhs)) {
                    0 => Some(self),
                    // rhs - r cannot overflow because r is smaller than rhs
                    r => self.checked_add(rhs - r)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                M.match_operator (|
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u32", "checked_rem", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let x := M.copy (| γ0_0 |) in
                          x));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                              |)
                            |)
                          |)))
                    ]
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let _ :=
                          M.is_constant_or_break_match (|
                            M.read (| γ |),
                            Value.Integer IntegerKind.U32 0
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let r := M.copy (| γ |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u32", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn is_multiple_of(self, rhs: Self) -> bool {
                match rhs {
                    0 => self == 0,
                    _ => self % rhs == 0,
                }
            }
    *)
    Definition is_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              rhs,
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.U32 0
                      |) in
                    M.alloc (|
                      BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.U32 0 |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      BinOp.eq (|
                        BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                        Value.Integer IntegerKind.U32 0
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_multiple_of :
      M.IsAssociatedFunction Self "is_multiple_of" is_multiple_of.
    
    (*
            pub const fn is_power_of_two(self) -> bool {
                self.count_ones() == 1
            }
    *)
    Definition is_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.eq (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u32", "count_ones", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U32 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_power_of_two :
      M.IsAssociatedFunction Self "is_power_of_two" is_power_of_two.
    
    (*
            const fn one_less_than_next_power_of_two(self) -> Self {
                if self <= 1 { return 0; }
    
                let p = self - 1;
                // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros.
                // That means the shift is always in-bounds, and some processors
                // (such as intel pre-haswell) have more efficient ctlz
                // intrinsics when the argument is non-zero.
                let z = unsafe { intrinsics::ctlz_nonzero(p) };
                <$SelfT>::MAX >> z
            }
    *)
    Definition one_less_than_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ 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 (|
                                BinOp.le (| M.read (| self |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U32 0 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ p :=
                  M.alloc (|
                    BinOp.Wrap.sub (| M.read (| self |), Value.Integer IntegerKind.U32 1 |)
                  |) in
                let~ z :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz_nonzero", [ Ty.path "u32" ] |),
                      [ M.read (| p |) ]
                    |)
                  |) in
                M.alloc (|
                  BinOp.Wrap.shr (|
                    M.read (| M.get_constant (| "core::num::MAX" |) |),
                    M.read (| z |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_one_less_than_next_power_of_two :
      M.IsAssociatedFunction Self "one_less_than_next_power_of_two" one_less_than_next_power_of_two.
    
    (*
            pub const fn next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two() + 1
            }
    *)
    Definition next_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.Wrap.add (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u32", "one_less_than_next_power_of_two", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U32 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_power_of_two :
      M.IsAssociatedFunction Self "next_power_of_two" next_power_of_two.
    
    (*
            pub const fn checked_next_power_of_two(self) -> Option<Self> {
                self.one_less_than_next_power_of_two().checked_add(1)
            }
    *)
    Definition checked_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "checked_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "u32",
                  "one_less_than_next_power_of_two",
                  []
                |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.U32 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_power_of_two :
      M.IsAssociatedFunction Self "checked_next_power_of_two" checked_next_power_of_two.
    
    (*
            pub const fn wrapping_next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two().wrapping_add(1)
            }
    *)
    Definition wrapping_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "wrapping_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "u32",
                  "one_less_than_next_power_of_two",
                  []
                |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.U32 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_next_power_of_two :
      M.IsAssociatedFunction Self "wrapping_next_power_of_two" wrapping_next_power_of_two.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u32", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u32", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "u32";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 4 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u32", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u32", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 4 ] [ Ty.path "u8" ];
                Ty.path "u32"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*         pub const fn min_value() -> Self { Self::MIN } *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*         pub const fn max_value() -> Self { Self::MAX } *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    
    (*
            pub const fn widening_mul(self, rhs: Self) -> (Self, Self) {
                // note: longer-term this should be done via an intrinsic,
                //   but for now we can deal without an impl for u128/i128
                // SAFETY: overflow will be contained within the wider types
                let wide = unsafe { (self as $WideT).unchecked_mul(rhs as $WideT) };
                (wide as $SelfT, (wide >> $BITS) as $SelfT)
            }
    *)
    Definition widening_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ wide :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "unchecked_mul", [] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.rust_cast (M.read (| wide |));
                  M.rust_cast
                    (BinOp.Wrap.shr (| M.read (| wide |), Value.Integer IntegerKind.I32 32 |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_widening_mul : M.IsAssociatedFunction Self "widening_mul" widening_mul.
    
    (*
            pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
                // note: longer-term this should be done via an intrinsic,
                //   but for now we can deal without an impl for u128/i128
                // SAFETY: overflow will be contained within the wider types
                let wide = unsafe {
                    (self as $WideT).unchecked_mul(rhs as $WideT).unchecked_add(carry as $WideT)
                };
                (wide as $SelfT, (wide >> $BITS) as $SelfT)
            }
    *)
    Definition carrying_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            let~ wide :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "unchecked_add", [] |),
                  [
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "u64", "unchecked_mul", [] |),
                      [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                    |);
                    M.rust_cast (M.read (| carry |))
                  ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.rust_cast (M.read (| wide |));
                  M.rust_cast
                    (BinOp.Wrap.shr (| M.read (| wide |), Value.Integer IntegerKind.I32 32 |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_mul : M.IsAssociatedFunction Self "carrying_mul" carrying_mul.
    
    (*
            pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
                ((self as $WideT + rhs as $WideT) / 2) as $SelfT
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.rust_cast
            (BinOp.Wrap.div (|
              BinOp.Wrap.add (| M.rust_cast (M.read (| self |)), M.rust_cast (M.read (| rhs |)) |),
              Value.Integer IntegerKind.U64 2
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    (*
                pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                    use self::IntErrorKind::*;
                    use self::ParseIntError as PIE;
    
                    if 2 > radix || radix > 36 {
                        from_str_radix_panic(radix);
                    }
    
                    if src.is_empty() {
                        return Err(PIE { kind: Empty });
                    }
    
                    #[allow(unused_comparisons)]
                    let is_signed_ty = 0 > <$int_ty>::MIN;
    
                    // all valid digits are ascii, so we will just iterate over the utf8 bytes
                    // and cast them to chars. .to_digit() will safely return None for anything
                    // other than a valid ascii digit for the given radix, including the first-byte
                    // of multi-byte sequences
                    let src = src.as_bytes();
    
                    let (is_positive, mut digits) = match src {
                        [b'+' | b'-'] => {
                            return Err(PIE { kind: InvalidDigit });
                        }
                        [b'+', rest @ ..] => (true, rest),
                        [b'-', rest @ ..] if is_signed_ty => (false, rest),
                        _ => (true, src),
                    };
    
                    let mut result = 0;
    
                    macro_rules! unwrap_or_PIE {
                        ($option:expr, $kind:ident) => {
                            match $option {
                                Some(value) => value,
                                None => return Err(PIE { kind: $kind }),
                            }
                        };
                    }
    
                    if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
                        // If the len of the str is short compared to the range of the type
                        // we are parsing into, then we can be certain that an overflow will not occur.
                        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
                        // above is a faster (conservative) approximation of this.
                        //
                        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
                        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
                        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
                        macro_rules! run_unchecked_loop {
                            ($unchecked_additive_op:tt) => {{
                                while let [c, rest @ ..] = digits {
                                    result = result * (radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit);
                                    result = result $unchecked_additive_op (x as $int_ty);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_unchecked_loop!(+)
                        } else {
                            run_unchecked_loop!(-)
                        };
                    } else {
                        macro_rules! run_checked_loop {
                            ($checked_additive_op:ident, $overflow_err:ident) => {{
                                while let [c, rest @ ..] = digits {
                                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
                                    // the compiler can use shifts if `radix` can be expressed as a
                                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
                                    // When the compiler can't use these optimisations,
                                    // the latency of the multiplication can be hidden by issuing it
                                    // before the result is needed to improve performance on
                                    // modern out-of-order CPU as multiplication here is slower
                                    // than the other instructions, we can get the end result faster
                                    // doing multiplication first and let the CPU spends other cycles
                                    // doing other computation and get multiplication result later.
                                    let mul = result.checked_mul(radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit) as $int_ty;
                                    result = unwrap_or_PIE!(mul, $overflow_err);
                                    result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_checked_loop!(checked_add, PosOverflow)
                        } else {
                            run_checked_loop!(checked_sub, NegOverflow)
                        };
                    }
                    Ok(result)
                }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) 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 (|
                                  BinOp.gt (|
                                    Value.Integer IntegerKind.U32 2,
                                    M.read (| radix |)
                                  |),
                                  ltac:(M.monadic
                                    (BinOp.gt (|
                                      M.read (| radix |),
                                      Value.Integer IntegerKind.U32 36
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::num::from_str_radix_panic", [] |),
                                [ M.read (| radix |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                                  [ M.read (| src |) ]
                                |)
                              |)) 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::num::error::ParseIntError"
                                        [
                                          ("kind",
                                            Value.StructTuple
                                              "core::num::error::IntErrorKind::Empty"
                                              [])
                                        ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ is_signed_ty :=
                  M.alloc (|
                    BinOp.gt (|
                      Value.Integer IntegerKind.U32 0,
                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                    |)
                  |) in
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| src |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.match_operator (|
                    src,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                          M.find_or_pattern (|
                            γ1_0,
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 43
                                    |) in
                                  Value.Tuple []));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 45
                                    |) in
                                  Value.Tuple []))
                            ],
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [] =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [
                                                  Value.StructRecord
                                                    "core::num::error::ParseIntError"
                                                    [
                                                      ("kind",
                                                        Value.StructTuple
                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                          [])
                                                    ]
                                                ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 43
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          M.alloc (| Value.Tuple [ Value.Bool true; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 45
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          let γ := is_signed_ty in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Tuple [ Value.Bool false; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (| Value.Tuple [ Value.Bool true; M.read (| src |) ] |)))
                    ]
                  |),
                  [
                    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 is_positive := M.copy (| γ0_0 |) in
                        let digits := M.copy (| γ0_1 |) in
                        let~ result := M.alloc (| Value.Integer IntegerKind.U32 0 |) 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::num::can_not_overflow",
                                            [ Ty.path "u32" ]
                                          |),
                                          [
                                            M.read (| radix |);
                                            M.read (| is_signed_ty |);
                                            M.read (| digits |)
                                          ]
                                        |)
                                      |)) 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 is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.read (| M.use radix |)
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.add (|
                                                              M.read (| result |),
                                                              M.read (| M.use x |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.read (| M.use radix |)
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.sub (|
                                                              M.read (| result |),
                                                              M.read (| M.use x |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ := M.use is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "u32",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.read (| M.use radix |)
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.use
                                                              (M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "char",
                                                                      "to_digit",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.rust_cast
                                                                        (M.read (|
                                                                          M.read (| c |)
                                                                        |));
                                                                      M.read (| radix |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "u32",
                                                                      "checked_add",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "u32",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.read (| M.use radix |)
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.use
                                                              (M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "char",
                                                                      "to_digit",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.rust_cast
                                                                        (M.read (|
                                                                          M.read (| c |)
                                                                        |));
                                                                      M.read (| radix |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "u32",
                                                                      "checked_sub",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_u32.
  
  Module Impl_u64.
    Definition Self : Ty.t := Ty.path "u64".
    
    (*         pub const MIN: Self = 0; *)
    (* Ty.path "u64" *)
    Definition value_MIN : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 0 |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = !0; *)
    (* Ty.path "u64" *)
    Definition value_MAX : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| UnOp.not (| Value.Integer IntegerKind.U64 0 |) |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = Self::MAX.count_ones(); *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u64", "count_ones", [] |),
              [ M.read (| M.get_constant (| "core::num::MAX" |) |) ]
            |)
          |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*
            pub const fn count_ones(self) -> u32 {
                return intrinsics::ctpop(self);
            }
    *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctpop", [ Ty.path "u64" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                return intrinsics::ctlz(self as $ActualT);
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz", [ Ty.path "u64" ] |),
                      [ M.read (| M.use self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                return intrinsics::cttz(self);
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::cttz", [ Ty.path "u64" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (!self).leading_zeros()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "leading_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (!self).trailing_zeros()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "trailing_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_signed(self) -> $SignedT {
                self as $SignedT
            }
    *)
    Definition cast_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_signed : M.IsAssociatedFunction Self "cast_signed" cast_signed.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                return intrinsics::rotate_left(self, n);
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_left", [ Ty.path "u64" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                return intrinsics::rotate_right(self, n);
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_right", [ Ty.path "u64" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                intrinsics::bswap(self as $ActualT) as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.use
              (M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::bswap", [ Ty.path "u64" ] |),
                  [ M.read (| M.use self |) ]
                |)
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                intrinsics::bitreverse(self as $ActualT) as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.use
              (M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::bitreverse", [ Ty.path "u64" ] |),
                  [ M.read (| M.use self |) ]
                |)
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                // This used to use `overflowing_add`, but that means it ends up being
                // a `wrapping_add`, losing some optimization opportunities. Notably,
                // phrasing it this way helps `.checked_add(1)` optimize to a check
                // against `MAX` and a `add nuw`.
                // Per <https://github.com/rust-lang/rust/pull/124114#issuecomment-2066173305>,
                // LLVM is happy to re-form the intrinsic later if useful.
    
                if unlikely!(intrinsics::add_with_overflow(self, rhs).1) {
                    None
                } else {
                    // SAFETY: Just checked it doesn't overflow
                    Some(unsafe { intrinsics::unchecked_add(self, rhs) })
                }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              M.read (|
                                M.SubPointer.get_tuple_field (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::intrinsics::add_with_overflow",
                                        [ Ty.path "u64" ]
                                      |),
                                      [ M.read (| self |); M.read (| rhs |) ]
                                    |)
                                  |),
                                  1
                                |)
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_add",
                              [ Ty.path "u64" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "u64" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_signed(self, rhs: $SignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_signed(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_signed :
      M.IsAssociatedFunction Self "checked_add_signed" checked_add_signed.
    
    (*
            pub const fn strict_add_signed(self, rhs: $SignedT) -> Self {
                let (a, b) = self.overflowing_add_signed(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_signed :
      M.IsAssociatedFunction Self "strict_add_signed" strict_add_signed.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                // Per PR#103299, there's no advantage to the `overflowing` intrinsic
                // for *unsigned* subtraction and we just emit the manual check anyway.
                // Thus, rather than using `overflowing_sub` that produces a wrapping
                // subtraction, check it ourself so we can use an unchecked one.
    
                if self < rhs {
                    None
                } else {
                    // SAFETY: just checked this can't overflow
                    Some(unsafe { intrinsics::unchecked_sub(self, rhs) })
                }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| rhs |) |) |)) 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_function (|
                              "core::intrinsics::unchecked_sub",
                              [ Ty.path "u64" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
             }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "u64" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_signed_diff(self, rhs: Self) -> Option<$SignedT> {
                let res = self.wrapping_sub(rhs) as $SignedT;
                let overflow = (self >= rhs) == (res < 0);
    
                if !overflow {
                    Some(res)
                } else {
                    None
                }
            }
    *)
    Definition checked_signed_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ res :=
              M.alloc (|
                M.rust_cast
                  (M.call_closure (|
                    M.get_associated_function (| Ty.path "u64", "wrapping_sub", [] |),
                    [ M.read (| self |); M.read (| rhs |) ]
                  |))
              |) in
            let~ overflow :=
              M.alloc (|
                BinOp.eq (|
                  BinOp.ge (| M.read (| self |), M.read (| rhs |) |),
                  BinOp.lt (| M.read (| res |), Value.Integer IntegerKind.I64 0 |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := M.use (M.alloc (| UnOp.not (| M.read (| overflow |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| res |) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_signed_diff :
      M.IsAssociatedFunction Self "checked_signed_diff" checked_signed_diff.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
             }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "u64" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U64 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "u64" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U64 0 |) ]
                          |)
                        |)) 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.path "u64", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U64 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "u64" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U64 0 |) ]
                          |)
                        |)) 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.path "u64", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.U64 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u64", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u64", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u64", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else if self < base {
                    Some(0)
                } else {
                    // Since base >= self, n >= 1
                    let mut n = 1;
                    let mut r = base;
    
                    // Optimization for 128 bit wide integers.
                    if Self::BITS == 128 {
                        // The following is a correct lower bound for ⌊log(base,self)⌋ because
                        //
                        // log(base,self) = log(2,self) / log(2,base)
                        //                ≥ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1)
                        //
                        // hence
                        //
                        // ⌊log(base,self)⌋ ≥ ⌊ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1) ⌋ .
                        n = self.ilog2() / (base.ilog2() + 1);
                        r = base.pow(n);
                    }
    
                    while r <= self / base {
                        n += 1;
                        r *= base;
                    }
                    Some(n)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.U64 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.U64 1 |)))
                          |)
                        |)) 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 (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| base |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::option::Option::Some"
                                [ Value.Integer IntegerKind.U32 0 ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let~ n := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                            let~ r := M.copy (| base |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            BinOp.eq (|
                                              M.read (| M.get_constant (| "core::num::BITS" |) |),
                                              Value.Integer IntegerKind.U32 128
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          n,
                                          BinOp.Wrap.div (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "u64",
                                                "ilog2",
                                                []
                                              |),
                                              [ M.read (| self |) ]
                                            |),
                                            BinOp.Wrap.add (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u64",
                                                  "ilog2",
                                                  []
                                                |),
                                                [ M.read (| base |) ]
                                              |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          r,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "u64",
                                              "pow",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| n |) ]
                                          |)
                                        |) in
                                      M.alloc (| Value.Tuple [] |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ _ :=
                              M.loop (|
                                ltac:(M.monadic
                                  (M.match_operator (|
                                    M.alloc (| Value.Tuple [] |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ :=
                                            M.use
                                              (M.alloc (|
                                                BinOp.le (|
                                                  M.read (| r |),
                                                  BinOp.Wrap.div (|
                                                    M.read (| self |),
                                                    M.read (| base |)
                                                  |)
                                                |)
                                              |)) in
                                          let _ :=
                                            M.is_constant_or_break_match (|
                                              M.read (| γ |),
                                              Value.Bool true
                                            |) in
                                          let~ _ :=
                                            let β := n in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.add (|
                                                M.read (| β |),
                                                Value.Integer IntegerKind.U32 1
                                              |)
                                            |) in
                                          let~ _ :=
                                            let β := r in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.mul (| M.read (| β |), M.read (| base |) |)
                                            |) 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 (|
                              Value.StructTuple "core::option::Option::Some" [ M.read (| n |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog2()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u64" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u64" ],
                              "ilog2",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog10()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u64" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u64" ],
                              "ilog10",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u64", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "u64"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u64", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u64", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "u64"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u64", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.U64 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U64 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u64",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u64",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U64 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U64 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "u64",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "u64", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "u64" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_signed(self, rhs: $SignedT) -> Self {
                let (res, overflow) = self.overflowing_add(rhs as Self);
                if overflow == (rhs < 0) {
                    res
                } else if overflow {
                    Self::MAX
                } else {
                    0
                }
            }
    *)
    Definition saturating_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflow := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| overflow |),
                                    BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I64 0 |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            res));
                        fun γ =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ := M.use overflow in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.get_constant (| "core::num::MAX" |)));
                                fun γ =>
                                  ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 0 |)))
                              ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_signed :
      M.IsAssociatedFunction Self "saturating_add_signed" saturating_add_signed.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "u64" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                // on unsigned types, there is no overflow in integer division
                self.wrapping_div(rhs)
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "wrapping_div", [] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "u64" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_signed(self, rhs: $SignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_signed :
      M.IsAssociatedFunction Self "wrapping_add_signed" wrapping_add_signed.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "u64" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "u64" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "wrapping_sub", [] |),
            [ M.read (| M.use (M.alloc (| Value.Integer IntegerKind.U64 0 |)) |); M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U64 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U64 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "u64",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "u64",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "u64", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "u64",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "u64",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "u64" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b || d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u64", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_signed(self, rhs: $SignedT) -> (Self, bool) {
                let (res, overflowed) = self.overflowing_add(rhs as Self);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I64 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_signed :
      M.IsAssociatedFunction Self "overflowing_add_signed" overflowing_add_signed.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "u64" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b || d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u64", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn abs_diff(self, other: Self) -> Self {
                if mem::size_of::<Self>() == 1 {
                    // Trick LLVM into generating the psadbw instruction when SSE2
                    // is available and this function is autovectorized for u8's.
                    (self as i32).wrapping_sub(other as i32).abs() as Self
                } else {
                    if self < other {
                        other - self
                    } else {
                        self - other
                    }
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.eq (|
                            M.call_closure (|
                              M.get_function (| "core::mem::size_of", [ Ty.path "u64" ] |),
                              []
                            |),
                            Value.Integer IntegerKind.Usize 1
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.rust_cast
                        (M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "abs", [] |),
                          [
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "i32", "wrapping_sub", [] |),
                              [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                            |)
                          ]
                        |))
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| other |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              BinOp.Wrap.sub (| M.read (| other |), M.read (| self |) |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (M.alloc (|
                              BinOp.Wrap.sub (| M.read (| self |), M.read (| other |) |)
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "u64" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                ((!self).wrapping_add(1), self != 0)
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "wrapping_add", [] |),
                [ UnOp.not (| M.read (| self |) |); Value.Integer IntegerKind.U64 1 ]
              |);
              BinOp.ne (| M.read (| self |), Value.Integer IntegerKind.U64 0 |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0{
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple [ Value.Integer IntegerKind.U64 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U64 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "u64",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "u64",
                                  "overflowing_mul",
                                  []
                                |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U64 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U64 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                let result = crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
    
                // Inform the optimizer what the range of outputs is. If testing
                // `core` crashes with no panic message and a `num::int_sqrt::u*`
                // test failed, it's because your edits caused these assertions or
                // the assertions in `fn isqrt` of `nonzero.rs` to become false.
                //
                // SAFETY: Integer square root is a monotonically nondecreasing
                // function, which means that increasing the input will never
                // cause the output to decrease. Thus, since the input for unsigned
                // integers is bounded by `[0, <$ActualT>::MAX]`, sqrt(n) will be
                // bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                unsafe {
                    const MAX_RESULT: $SelfT = crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
                    crate::hint::assert_unchecked(result <= MAX_RESULT);
                }
    
                result
            }
    *)
    Definition isqrt (ε : 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~ result :=
              M.copy (|
                M.use
                  (M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::num::int_sqrt::u64", [] |),
                      [ M.read (| M.use self |) ]
                    |)
                  |))
              |) in
            let~ _ :=
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (| "core::hint::assert_unchecked", [] |),
                    [
                      BinOp.le (|
                        M.read (| result |),
                        M.read (| M.get_constant (| "core::num::isqrt::MAX_RESULT" |) |)
                      |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |) in
            result
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
                if r > 0 {
                    d + 1
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| r |), Value.Integer IntegerKind.U64 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      BinOp.Wrap.add (| M.read (| d |), Value.Integer IntegerKind.U64 1 |)
                    |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                match self % rhs {
                    0 => self,
                    r => self + (rhs - r)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.U64 0
                      |) in
                    self));
                fun γ =>
                  ltac:(M.monadic
                    (let r := M.copy (| γ |) in
                    M.alloc (|
                      BinOp.Wrap.add (|
                        M.read (| self |),
                        BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                match try_opt!(self.checked_rem(rhs)) {
                    0 => Some(self),
                    // rhs - r cannot overflow because r is smaller than rhs
                    r => self.checked_add(rhs - r)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                M.match_operator (|
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u64", "checked_rem", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let x := M.copy (| γ0_0 |) in
                          x));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                              |)
                            |)
                          |)))
                    ]
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let _ :=
                          M.is_constant_or_break_match (|
                            M.read (| γ |),
                            Value.Integer IntegerKind.U64 0
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let r := M.copy (| γ |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u64", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn is_multiple_of(self, rhs: Self) -> bool {
                match rhs {
                    0 => self == 0,
                    _ => self % rhs == 0,
                }
            }
    *)
    Definition is_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              rhs,
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.U64 0
                      |) in
                    M.alloc (|
                      BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.U64 0 |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      BinOp.eq (|
                        BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                        Value.Integer IntegerKind.U64 0
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_multiple_of :
      M.IsAssociatedFunction Self "is_multiple_of" is_multiple_of.
    
    (*
            pub const fn is_power_of_two(self) -> bool {
                self.count_ones() == 1
            }
    *)
    Definition is_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.eq (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u64", "count_ones", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U32 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_power_of_two :
      M.IsAssociatedFunction Self "is_power_of_two" is_power_of_two.
    
    (*
            const fn one_less_than_next_power_of_two(self) -> Self {
                if self <= 1 { return 0; }
    
                let p = self - 1;
                // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros.
                // That means the shift is always in-bounds, and some processors
                // (such as intel pre-haswell) have more efficient ctlz
                // intrinsics when the argument is non-zero.
                let z = unsafe { intrinsics::ctlz_nonzero(p) };
                <$SelfT>::MAX >> z
            }
    *)
    Definition one_less_than_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ 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 (|
                                BinOp.le (| M.read (| self |), Value.Integer IntegerKind.U64 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.Integer IntegerKind.U64 0 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ p :=
                  M.alloc (|
                    BinOp.Wrap.sub (| M.read (| self |), Value.Integer IntegerKind.U64 1 |)
                  |) in
                let~ z :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz_nonzero", [ Ty.path "u64" ] |),
                      [ M.read (| p |) ]
                    |)
                  |) in
                M.alloc (|
                  BinOp.Wrap.shr (|
                    M.read (| M.get_constant (| "core::num::MAX" |) |),
                    M.read (| z |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_one_less_than_next_power_of_two :
      M.IsAssociatedFunction Self "one_less_than_next_power_of_two" one_less_than_next_power_of_two.
    
    (*
            pub const fn next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two() + 1
            }
    *)
    Definition next_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.Wrap.add (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u64", "one_less_than_next_power_of_two", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U64 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_power_of_two :
      M.IsAssociatedFunction Self "next_power_of_two" next_power_of_two.
    
    (*
            pub const fn checked_next_power_of_two(self) -> Option<Self> {
                self.one_less_than_next_power_of_two().checked_add(1)
            }
    *)
    Definition checked_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "checked_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "u64",
                  "one_less_than_next_power_of_two",
                  []
                |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.U64 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_power_of_two :
      M.IsAssociatedFunction Self "checked_next_power_of_two" checked_next_power_of_two.
    
    (*
            pub const fn wrapping_next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two().wrapping_add(1)
            }
    *)
    Definition wrapping_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "wrapping_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "u64",
                  "one_less_than_next_power_of_two",
                  []
                |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.U64 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_next_power_of_two :
      M.IsAssociatedFunction Self "wrapping_next_power_of_two" wrapping_next_power_of_two.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "u64";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 8 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 8 ] [ Ty.path "u8" ];
                Ty.path "u64"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*         pub const fn min_value() -> Self { Self::MIN } *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*         pub const fn max_value() -> Self { Self::MAX } *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    
    (*
            pub const fn widening_mul(self, rhs: Self) -> (Self, Self) {
                // note: longer-term this should be done via an intrinsic,
                //   but for now we can deal without an impl for u128/i128
                // SAFETY: overflow will be contained within the wider types
                let wide = unsafe { (self as $WideT).unchecked_mul(rhs as $WideT) };
                (wide as $SelfT, (wide >> $BITS) as $SelfT)
            }
    *)
    Definition widening_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ wide :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "unchecked_mul", [] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.rust_cast (M.read (| wide |));
                  M.rust_cast
                    (BinOp.Wrap.shr (| M.read (| wide |), Value.Integer IntegerKind.I32 64 |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_widening_mul : M.IsAssociatedFunction Self "widening_mul" widening_mul.
    
    (*
            pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
                // note: longer-term this should be done via an intrinsic,
                //   but for now we can deal without an impl for u128/i128
                // SAFETY: overflow will be contained within the wider types
                let wide = unsafe {
                    (self as $WideT).unchecked_mul(rhs as $WideT).unchecked_add(carry as $WideT)
                };
                (wide as $SelfT, (wide >> $BITS) as $SelfT)
            }
    *)
    Definition carrying_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            let~ wide :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "unchecked_add", [] |),
                  [
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "u128", "unchecked_mul", [] |),
                      [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                    |);
                    M.rust_cast (M.read (| carry |))
                  ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.rust_cast (M.read (| wide |));
                  M.rust_cast
                    (BinOp.Wrap.shr (| M.read (| wide |), Value.Integer IntegerKind.I32 64 |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_mul : M.IsAssociatedFunction Self "carrying_mul" carrying_mul.
    
    (*
            pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
                ((self as $WideT + rhs as $WideT) / 2) as $SelfT
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.rust_cast
            (BinOp.Wrap.div (|
              BinOp.Wrap.add (| M.rust_cast (M.read (| self |)), M.rust_cast (M.read (| rhs |)) |),
              Value.Integer IntegerKind.U128 2
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    (*
                pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                    use self::IntErrorKind::*;
                    use self::ParseIntError as PIE;
    
                    if 2 > radix || radix > 36 {
                        from_str_radix_panic(radix);
                    }
    
                    if src.is_empty() {
                        return Err(PIE { kind: Empty });
                    }
    
                    #[allow(unused_comparisons)]
                    let is_signed_ty = 0 > <$int_ty>::MIN;
    
                    // all valid digits are ascii, so we will just iterate over the utf8 bytes
                    // and cast them to chars. .to_digit() will safely return None for anything
                    // other than a valid ascii digit for the given radix, including the first-byte
                    // of multi-byte sequences
                    let src = src.as_bytes();
    
                    let (is_positive, mut digits) = match src {
                        [b'+' | b'-'] => {
                            return Err(PIE { kind: InvalidDigit });
                        }
                        [b'+', rest @ ..] => (true, rest),
                        [b'-', rest @ ..] if is_signed_ty => (false, rest),
                        _ => (true, src),
                    };
    
                    let mut result = 0;
    
                    macro_rules! unwrap_or_PIE {
                        ($option:expr, $kind:ident) => {
                            match $option {
                                Some(value) => value,
                                None => return Err(PIE { kind: $kind }),
                            }
                        };
                    }
    
                    if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
                        // If the len of the str is short compared to the range of the type
                        // we are parsing into, then we can be certain that an overflow will not occur.
                        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
                        // above is a faster (conservative) approximation of this.
                        //
                        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
                        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
                        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
                        macro_rules! run_unchecked_loop {
                            ($unchecked_additive_op:tt) => {{
                                while let [c, rest @ ..] = digits {
                                    result = result * (radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit);
                                    result = result $unchecked_additive_op (x as $int_ty);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_unchecked_loop!(+)
                        } else {
                            run_unchecked_loop!(-)
                        };
                    } else {
                        macro_rules! run_checked_loop {
                            ($checked_additive_op:ident, $overflow_err:ident) => {{
                                while let [c, rest @ ..] = digits {
                                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
                                    // the compiler can use shifts if `radix` can be expressed as a
                                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
                                    // When the compiler can't use these optimisations,
                                    // the latency of the multiplication can be hidden by issuing it
                                    // before the result is needed to improve performance on
                                    // modern out-of-order CPU as multiplication here is slower
                                    // than the other instructions, we can get the end result faster
                                    // doing multiplication first and let the CPU spends other cycles
                                    // doing other computation and get multiplication result later.
                                    let mul = result.checked_mul(radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit) as $int_ty;
                                    result = unwrap_or_PIE!(mul, $overflow_err);
                                    result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_checked_loop!(checked_add, PosOverflow)
                        } else {
                            run_checked_loop!(checked_sub, NegOverflow)
                        };
                    }
                    Ok(result)
                }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) 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 (|
                                  BinOp.gt (|
                                    Value.Integer IntegerKind.U32 2,
                                    M.read (| radix |)
                                  |),
                                  ltac:(M.monadic
                                    (BinOp.gt (|
                                      M.read (| radix |),
                                      Value.Integer IntegerKind.U32 36
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::num::from_str_radix_panic", [] |),
                                [ M.read (| radix |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                                  [ M.read (| src |) ]
                                |)
                              |)) 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::num::error::ParseIntError"
                                        [
                                          ("kind",
                                            Value.StructTuple
                                              "core::num::error::IntErrorKind::Empty"
                                              [])
                                        ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ is_signed_ty :=
                  M.alloc (|
                    BinOp.gt (|
                      Value.Integer IntegerKind.U64 0,
                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                    |)
                  |) in
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| src |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.match_operator (|
                    src,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                          M.find_or_pattern (|
                            γ1_0,
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 43
                                    |) in
                                  Value.Tuple []));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 45
                                    |) in
                                  Value.Tuple []))
                            ],
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [] =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [
                                                  Value.StructRecord
                                                    "core::num::error::ParseIntError"
                                                    [
                                                      ("kind",
                                                        Value.StructTuple
                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                          [])
                                                    ]
                                                ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 43
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          M.alloc (| Value.Tuple [ Value.Bool true; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 45
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          let γ := is_signed_ty in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Tuple [ Value.Bool false; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (| Value.Tuple [ Value.Bool true; M.read (| src |) ] |)))
                    ]
                  |),
                  [
                    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 is_positive := M.copy (| γ0_0 |) in
                        let digits := M.copy (| γ0_1 |) in
                        let~ result := M.alloc (| Value.Integer IntegerKind.U64 0 |) 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::num::can_not_overflow",
                                            [ Ty.path "u64" ]
                                          |),
                                          [
                                            M.read (| radix |);
                                            M.read (| is_signed_ty |);
                                            M.read (| digits |)
                                          ]
                                        |)
                                      |)) 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 is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.add (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.sub (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ := M.use is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "u64",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "u64",
                                                                      "checked_add",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "u64",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "u64",
                                                                      "checked_sub",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_u64.
  
  Module Impl_u128.
    Definition Self : Ty.t := Ty.path "u128".
    
    (*         pub const MIN: Self = 0; *)
    (* Ty.path "u128" *)
    Definition value_MIN : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 0 |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = !0; *)
    (* Ty.path "u128" *)
    Definition value_MAX : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| UnOp.not (| Value.Integer IntegerKind.U128 0 |) |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = Self::MAX.count_ones(); *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u128", "count_ones", [] |),
              [ M.read (| M.get_constant (| "core::num::MAX" |) |) ]
            |)
          |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*
            pub const fn count_ones(self) -> u32 {
                return intrinsics::ctpop(self);
            }
    *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctpop", [ Ty.path "u128" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                return intrinsics::ctlz(self as $ActualT);
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz", [ Ty.path "u128" ] |),
                      [ M.read (| M.use self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                return intrinsics::cttz(self);
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::cttz", [ Ty.path "u128" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (!self).leading_zeros()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "leading_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (!self).trailing_zeros()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "trailing_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_signed(self) -> $SignedT {
                self as $SignedT
            }
    *)
    Definition cast_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_signed : M.IsAssociatedFunction Self "cast_signed" cast_signed.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                return intrinsics::rotate_left(self, n);
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_left", [ Ty.path "u128" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                return intrinsics::rotate_right(self, n);
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_right", [ Ty.path "u128" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                intrinsics::bswap(self as $ActualT) as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.use
              (M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::bswap", [ Ty.path "u128" ] |),
                  [ M.read (| M.use self |) ]
                |)
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                intrinsics::bitreverse(self as $ActualT) as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.use
              (M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::bitreverse", [ Ty.path "u128" ] |),
                  [ M.read (| M.use self |) ]
                |)
              |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                // This used to use `overflowing_add`, but that means it ends up being
                // a `wrapping_add`, losing some optimization opportunities. Notably,
                // phrasing it this way helps `.checked_add(1)` optimize to a check
                // against `MAX` and a `add nuw`.
                // Per <https://github.com/rust-lang/rust/pull/124114#issuecomment-2066173305>,
                // LLVM is happy to re-form the intrinsic later if useful.
    
                if unlikely!(intrinsics::add_with_overflow(self, rhs).1) {
                    None
                } else {
                    // SAFETY: Just checked it doesn't overflow
                    Some(unsafe { intrinsics::unchecked_add(self, rhs) })
                }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              M.read (|
                                M.SubPointer.get_tuple_field (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::intrinsics::add_with_overflow",
                                        [ Ty.path "u128" ]
                                      |),
                                      [ M.read (| self |); M.read (| rhs |) ]
                                    |)
                                  |),
                                  1
                                |)
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_add",
                              [ Ty.path "u128" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "u128" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_signed(self, rhs: $SignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_signed(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_signed :
      M.IsAssociatedFunction Self "checked_add_signed" checked_add_signed.
    
    (*
            pub const fn strict_add_signed(self, rhs: $SignedT) -> Self {
                let (a, b) = self.overflowing_add_signed(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_signed :
      M.IsAssociatedFunction Self "strict_add_signed" strict_add_signed.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                // Per PR#103299, there's no advantage to the `overflowing` intrinsic
                // for *unsigned* subtraction and we just emit the manual check anyway.
                // Thus, rather than using `overflowing_sub` that produces a wrapping
                // subtraction, check it ourself so we can use an unchecked one.
    
                if self < rhs {
                    None
                } else {
                    // SAFETY: just checked this can't overflow
                    Some(unsafe { intrinsics::unchecked_sub(self, rhs) })
                }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| rhs |) |) |)) 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_function (|
                              "core::intrinsics::unchecked_sub",
                              [ Ty.path "u128" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
             }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "u128" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_signed_diff(self, rhs: Self) -> Option<$SignedT> {
                let res = self.wrapping_sub(rhs) as $SignedT;
                let overflow = (self >= rhs) == (res < 0);
    
                if !overflow {
                    Some(res)
                } else {
                    None
                }
            }
    *)
    Definition checked_signed_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ res :=
              M.alloc (|
                M.rust_cast
                  (M.call_closure (|
                    M.get_associated_function (| Ty.path "u128", "wrapping_sub", [] |),
                    [ M.read (| self |); M.read (| rhs |) ]
                  |))
              |) in
            let~ overflow :=
              M.alloc (|
                BinOp.eq (|
                  BinOp.ge (| M.read (| self |), M.read (| rhs |) |),
                  BinOp.lt (| M.read (| res |), Value.Integer IntegerKind.I128 0 |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := M.use (M.alloc (| UnOp.not (| M.read (| overflow |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| res |) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_signed_diff :
      M.IsAssociatedFunction Self "checked_signed_diff" checked_signed_diff.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
             }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "u128" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U128 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "u128" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U128 0 |) ]
                          |)
                        |)) 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.path "u128", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U128 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "u128" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.U128 0 |) ]
                          |)
                        |)) 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.path "u128", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.U128 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u128", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u128", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u128", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else if self < base {
                    Some(0)
                } else {
                    // Since base >= self, n >= 1
                    let mut n = 1;
                    let mut r = base;
    
                    // Optimization for 128 bit wide integers.
                    if Self::BITS == 128 {
                        // The following is a correct lower bound for ⌊log(base,self)⌋ because
                        //
                        // log(base,self) = log(2,self) / log(2,base)
                        //                ≥ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1)
                        //
                        // hence
                        //
                        // ⌊log(base,self)⌋ ≥ ⌊ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1) ⌋ .
                        n = self.ilog2() / (base.ilog2() + 1);
                        r = base.pow(n);
                    }
    
                    while r <= self / base {
                        n += 1;
                        r *= base;
                    }
                    Some(n)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.U128 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.U128 1 |)))
                          |)
                        |)) 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 (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| base |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::option::Option::Some"
                                [ Value.Integer IntegerKind.U32 0 ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let~ n := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                            let~ r := M.copy (| base |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            BinOp.eq (|
                                              M.read (| M.get_constant (| "core::num::BITS" |) |),
                                              Value.Integer IntegerKind.U32 128
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          n,
                                          BinOp.Wrap.div (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "u128",
                                                "ilog2",
                                                []
                                              |),
                                              [ M.read (| self |) ]
                                            |),
                                            BinOp.Wrap.add (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u128",
                                                  "ilog2",
                                                  []
                                                |),
                                                [ M.read (| base |) ]
                                              |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          r,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "u128",
                                              "pow",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| n |) ]
                                          |)
                                        |) in
                                      M.alloc (| Value.Tuple [] |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ _ :=
                              M.loop (|
                                ltac:(M.monadic
                                  (M.match_operator (|
                                    M.alloc (| Value.Tuple [] |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ :=
                                            M.use
                                              (M.alloc (|
                                                BinOp.le (|
                                                  M.read (| r |),
                                                  BinOp.Wrap.div (|
                                                    M.read (| self |),
                                                    M.read (| base |)
                                                  |)
                                                |)
                                              |)) in
                                          let _ :=
                                            M.is_constant_or_break_match (|
                                              M.read (| γ |),
                                              Value.Bool true
                                            |) in
                                          let~ _ :=
                                            let β := n in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.add (|
                                                M.read (| β |),
                                                Value.Integer IntegerKind.U32 1
                                              |)
                                            |) in
                                          let~ _ :=
                                            let β := r in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.mul (| M.read (| β |), M.read (| base |) |)
                                            |) 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 (|
                              Value.StructTuple "core::option::Option::Some" [ M.read (| n |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog2()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u128" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "core::num::nonzero::NonZero")
                                []
                                [ Ty.path "u128" ],
                              "ilog2",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog10()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "u128" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "core::num::nonzero::NonZero")
                                []
                                [ Ty.path "u128" ],
                              "ilog10",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u128", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "u128"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u128", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u128", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "u128"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u128", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.U128 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U128 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "u128",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u128",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U128 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U128 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "u128",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "u128", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "u128" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_signed(self, rhs: $SignedT) -> Self {
                let (res, overflow) = self.overflowing_add(rhs as Self);
                if overflow == (rhs < 0) {
                    res
                } else if overflow {
                    Self::MAX
                } else {
                    0
                }
            }
    *)
    Definition saturating_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflow := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| overflow |),
                                    BinOp.lt (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.I128 0
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            res));
                        fun γ =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ := M.use overflow in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.get_constant (| "core::num::MAX" |)));
                                fun γ =>
                                  ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 0 |)))
                              ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_signed :
      M.IsAssociatedFunction Self "saturating_add_signed" saturating_add_signed.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "u128" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                // on unsigned types, there is no overflow in integer division
                self.wrapping_div(rhs)
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "wrapping_div", [] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "u128" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_signed(self, rhs: $SignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_signed :
      M.IsAssociatedFunction Self "wrapping_add_signed" wrapping_add_signed.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "u128" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "u128" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "wrapping_sub", [] |),
            [ M.read (| M.use (M.alloc (| Value.Integer IntegerKind.U128 0 |)) |); M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U128 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U128 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "u128",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "u128",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "u128", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "u128",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "u128",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "u128" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b || d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u128", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_signed(self, rhs: $SignedT) -> (Self, bool) {
                let (res, overflowed) = self.overflowing_add(rhs as Self);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.I128 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_signed :
      M.IsAssociatedFunction Self "overflowing_add_signed" overflowing_add_signed.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "u128" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b || d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "u128", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn abs_diff(self, other: Self) -> Self {
                if mem::size_of::<Self>() == 1 {
                    // Trick LLVM into generating the psadbw instruction when SSE2
                    // is available and this function is autovectorized for u8's.
                    (self as i32).wrapping_sub(other as i32).abs() as Self
                } else {
                    if self < other {
                        other - self
                    } else {
                        self - other
                    }
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.eq (|
                            M.call_closure (|
                              M.get_function (| "core::mem::size_of", [ Ty.path "u128" ] |),
                              []
                            |),
                            Value.Integer IntegerKind.Usize 1
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.rust_cast
                        (M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "abs", [] |),
                          [
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "i32", "wrapping_sub", [] |),
                              [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                            |)
                          ]
                        |))
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| other |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              BinOp.Wrap.sub (| M.read (| other |), M.read (| self |) |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (M.alloc (|
                              BinOp.Wrap.sub (| M.read (| self |), M.read (| other |) |)
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "u128" ] |),
                  [ M.read (| M.use self |); M.read (| M.use rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.read (| M.use a |); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                ((!self).wrapping_add(1), self != 0)
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u128", "wrapping_add", [] |),
                [ UnOp.not (| M.read (| self |) |); Value.Integer IntegerKind.U128 1 ]
              |);
              BinOp.ne (| M.read (| self |), Value.Integer IntegerKind.U128 0 |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u128", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u128", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0{
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple [ Value.Integer IntegerKind.U128 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U128 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "u128",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "u128",
                                  "overflowing_mul",
                                  []
                                |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.U128 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.U128 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                let result = crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
    
                // Inform the optimizer what the range of outputs is. If testing
                // `core` crashes with no panic message and a `num::int_sqrt::u*`
                // test failed, it's because your edits caused these assertions or
                // the assertions in `fn isqrt` of `nonzero.rs` to become false.
                //
                // SAFETY: Integer square root is a monotonically nondecreasing
                // function, which means that increasing the input will never
                // cause the output to decrease. Thus, since the input for unsigned
                // integers is bounded by `[0, <$ActualT>::MAX]`, sqrt(n) will be
                // bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                unsafe {
                    const MAX_RESULT: $SelfT = crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
                    crate::hint::assert_unchecked(result <= MAX_RESULT);
                }
    
                result
            }
    *)
    Definition isqrt (ε : 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~ result :=
              M.copy (|
                M.use
                  (M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::num::int_sqrt::u128", [] |),
                      [ M.read (| M.use self |) ]
                    |)
                  |))
              |) in
            let~ _ :=
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (| "core::hint::assert_unchecked", [] |),
                    [
                      BinOp.le (|
                        M.read (| result |),
                        M.read (| M.get_constant (| "core::num::isqrt::MAX_RESULT" |) |)
                      |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |) in
            result
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
                if r > 0 {
                    d + 1
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| r |), Value.Integer IntegerKind.U128 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      BinOp.Wrap.add (| M.read (| d |), Value.Integer IntegerKind.U128 1 |)
                    |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                match self % rhs {
                    0 => self,
                    r => self + (rhs - r)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.U128 0
                      |) in
                    self));
                fun γ =>
                  ltac:(M.monadic
                    (let r := M.copy (| γ |) in
                    M.alloc (|
                      BinOp.Wrap.add (|
                        M.read (| self |),
                        BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                match try_opt!(self.checked_rem(rhs)) {
                    0 => Some(self),
                    // rhs - r cannot overflow because r is smaller than rhs
                    r => self.checked_add(rhs - r)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                M.match_operator (|
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "u128", "checked_rem", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let x := M.copy (| γ0_0 |) in
                          x));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                              |)
                            |)
                          |)))
                    ]
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let _ :=
                          M.is_constant_or_break_match (|
                            M.read (| γ |),
                            Value.Integer IntegerKind.U128 0
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let r := M.copy (| γ |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "u128", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn is_multiple_of(self, rhs: Self) -> bool {
                match rhs {
                    0 => self == 0,
                    _ => self % rhs == 0,
                }
            }
    *)
    Definition is_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              rhs,
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.U128 0
                      |) in
                    M.alloc (|
                      BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.U128 0 |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      BinOp.eq (|
                        BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                        Value.Integer IntegerKind.U128 0
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_multiple_of :
      M.IsAssociatedFunction Self "is_multiple_of" is_multiple_of.
    
    (*
            pub const fn is_power_of_two(self) -> bool {
                self.count_ones() == 1
            }
    *)
    Definition is_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.eq (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u128", "count_ones", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U32 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_power_of_two :
      M.IsAssociatedFunction Self "is_power_of_two" is_power_of_two.
    
    (*
            const fn one_less_than_next_power_of_two(self) -> Self {
                if self <= 1 { return 0; }
    
                let p = self - 1;
                // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros.
                // That means the shift is always in-bounds, and some processors
                // (such as intel pre-haswell) have more efficient ctlz
                // intrinsics when the argument is non-zero.
                let z = unsafe { intrinsics::ctlz_nonzero(p) };
                <$SelfT>::MAX >> z
            }
    *)
    Definition one_less_than_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ 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 (|
                                BinOp.le (| M.read (| self |), Value.Integer IntegerKind.U128 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.Integer IntegerKind.U128 0 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ p :=
                  M.alloc (|
                    BinOp.Wrap.sub (| M.read (| self |), Value.Integer IntegerKind.U128 1 |)
                  |) in
                let~ z :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz_nonzero", [ Ty.path "u128" ] |),
                      [ M.read (| p |) ]
                    |)
                  |) in
                M.alloc (|
                  BinOp.Wrap.shr (|
                    M.read (| M.get_constant (| "core::num::MAX" |) |),
                    M.read (| z |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_one_less_than_next_power_of_two :
      M.IsAssociatedFunction Self "one_less_than_next_power_of_two" one_less_than_next_power_of_two.
    
    (*
            pub const fn next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two() + 1
            }
    *)
    Definition next_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.Wrap.add (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u128", "one_less_than_next_power_of_two", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U128 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_power_of_two :
      M.IsAssociatedFunction Self "next_power_of_two" next_power_of_two.
    
    (*
            pub const fn checked_next_power_of_two(self) -> Option<Self> {
                self.one_less_than_next_power_of_two().checked_add(1)
            }
    *)
    Definition checked_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "checked_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "u128",
                  "one_less_than_next_power_of_two",
                  []
                |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.U128 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_power_of_two :
      M.IsAssociatedFunction Self "checked_next_power_of_two" checked_next_power_of_two.
    
    (*
            pub const fn wrapping_next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two().wrapping_add(1)
            }
    *)
    Definition wrapping_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "wrapping_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "u128",
                  "one_less_than_next_power_of_two",
                  []
                |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.U128 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_next_power_of_two :
      M.IsAssociatedFunction Self "wrapping_next_power_of_two" wrapping_next_power_of_two.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u128", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u128", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "u128";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 16 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u128", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u128", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 16 ] [ Ty.path "u8" ];
                Ty.path "u128"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*         pub const fn min_value() -> Self { Self::MIN } *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*         pub const fn max_value() -> Self { Self::MAX } *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    
    (*
            pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
                // Use the well known branchless algorithm from Hacker's Delight to compute
                // `(a + b) / 2` without overflowing: `((a ^ b) >> 1) + (a & b)`.
                ((self ^ rhs) >> 1) + (self & rhs)
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.add (|
            BinOp.Wrap.shr (|
              BinOp.bit_xor (M.read (| self |)) (M.read (| rhs |)),
              Value.Integer IntegerKind.I32 1
            |),
            BinOp.bit_and (M.read (| self |)) (M.read (| rhs |))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    (*
                pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                    use self::IntErrorKind::*;
                    use self::ParseIntError as PIE;
    
                    if 2 > radix || radix > 36 {
                        from_str_radix_panic(radix);
                    }
    
                    if src.is_empty() {
                        return Err(PIE { kind: Empty });
                    }
    
                    #[allow(unused_comparisons)]
                    let is_signed_ty = 0 > <$int_ty>::MIN;
    
                    // all valid digits are ascii, so we will just iterate over the utf8 bytes
                    // and cast them to chars. .to_digit() will safely return None for anything
                    // other than a valid ascii digit for the given radix, including the first-byte
                    // of multi-byte sequences
                    let src = src.as_bytes();
    
                    let (is_positive, mut digits) = match src {
                        [b'+' | b'-'] => {
                            return Err(PIE { kind: InvalidDigit });
                        }
                        [b'+', rest @ ..] => (true, rest),
                        [b'-', rest @ ..] if is_signed_ty => (false, rest),
                        _ => (true, src),
                    };
    
                    let mut result = 0;
    
                    macro_rules! unwrap_or_PIE {
                        ($option:expr, $kind:ident) => {
                            match $option {
                                Some(value) => value,
                                None => return Err(PIE { kind: $kind }),
                            }
                        };
                    }
    
                    if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
                        // If the len of the str is short compared to the range of the type
                        // we are parsing into, then we can be certain that an overflow will not occur.
                        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
                        // above is a faster (conservative) approximation of this.
                        //
                        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
                        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
                        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
                        macro_rules! run_unchecked_loop {
                            ($unchecked_additive_op:tt) => {{
                                while let [c, rest @ ..] = digits {
                                    result = result * (radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit);
                                    result = result $unchecked_additive_op (x as $int_ty);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_unchecked_loop!(+)
                        } else {
                            run_unchecked_loop!(-)
                        };
                    } else {
                        macro_rules! run_checked_loop {
                            ($checked_additive_op:ident, $overflow_err:ident) => {{
                                while let [c, rest @ ..] = digits {
                                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
                                    // the compiler can use shifts if `radix` can be expressed as a
                                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
                                    // When the compiler can't use these optimisations,
                                    // the latency of the multiplication can be hidden by issuing it
                                    // before the result is needed to improve performance on
                                    // modern out-of-order CPU as multiplication here is slower
                                    // than the other instructions, we can get the end result faster
                                    // doing multiplication first and let the CPU spends other cycles
                                    // doing other computation and get multiplication result later.
                                    let mul = result.checked_mul(radix as $int_ty);
                                    let x = unwrap_or_PIE!(( *c as char).to_digit(radix), InvalidDigit) as $int_ty;
                                    result = unwrap_or_PIE!(mul, $overflow_err);
                                    result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
                                    digits = rest;
                                }
                            }};
                        }
                        if is_positive {
                            run_checked_loop!(checked_add, PosOverflow)
                        } else {
                            run_checked_loop!(checked_sub, NegOverflow)
                        };
                    }
                    Ok(result)
                }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) 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 (|
                                  BinOp.gt (|
                                    Value.Integer IntegerKind.U32 2,
                                    M.read (| radix |)
                                  |),
                                  ltac:(M.monadic
                                    (BinOp.gt (|
                                      M.read (| radix |),
                                      Value.Integer IntegerKind.U32 36
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::num::from_str_radix_panic", [] |),
                                [ M.read (| radix |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                                  [ M.read (| src |) ]
                                |)
                              |)) 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::num::error::ParseIntError"
                                        [
                                          ("kind",
                                            Value.StructTuple
                                              "core::num::error::IntErrorKind::Empty"
                                              [])
                                        ]
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ is_signed_ty :=
                  M.alloc (|
                    BinOp.gt (|
                      Value.Integer IntegerKind.U128 0,
                      M.read (| M.get_constant (| "core::num::MIN" |) |)
                    |)
                  |) in
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| src |) ]
                    |)
                  |) in
                M.match_operator (|
                  M.match_operator (|
                    src,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 := M.SubPointer.get_slice_index (| γ, 0 |) in
                          M.find_or_pattern (|
                            γ1_0,
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 43
                                    |) in
                                  Value.Tuple []));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Integer IntegerKind.U8 45
                                    |) in
                                  Value.Tuple []))
                            ],
                            M.closure
                              (fun γ =>
                                ltac:(M.monadic
                                  match γ with
                                  | [] =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [
                                                  Value.StructRecord
                                                    "core::num::error::ParseIntError"
                                                    [
                                                      ("kind",
                                                        Value.StructTuple
                                                          "core::num::error::IntErrorKind::InvalidDigit"
                                                          [])
                                                    ]
                                                ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                  | _ => M.impossible "wrong number of arguments"
                                  end))
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 43
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          M.alloc (| Value.Tuple [ Value.Bool true; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (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 _ :=
                            M.is_constant_or_break_match (|
                              M.read (| γ1_0 |),
                              Value.Integer IntegerKind.U8 45
                            |) in
                          let rest := M.alloc (| γ1_rest |) in
                          let γ := is_signed_ty in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Tuple [ Value.Bool false; M.read (| rest |) ] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (| Value.Tuple [ Value.Bool true; M.read (| src |) ] |)))
                    ]
                  |),
                  [
                    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 is_positive := M.copy (| γ0_0 |) in
                        let digits := M.copy (| γ0_1 |) in
                        let~ result := M.alloc (| Value.Integer IntegerKind.U128 0 |) 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::num::can_not_overflow",
                                            [ Ty.path "u128" ]
                                          |),
                                          [
                                            M.read (| radix |);
                                            M.read (| is_signed_ty |);
                                            M.read (| digits |)
                                          ]
                                        |)
                                      |)) 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 is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.add (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.mul (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| radix |))
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.copy (|
                                                            M.match_operator (|
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path "char",
                                                                    "to_digit",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.rust_cast
                                                                      (M.read (| M.read (| c |) |));
                                                                    M.read (| radix |)
                                                                  ]
                                                                |)
                                                              |),
                                                              [
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let γ0_0 :=
                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                        γ,
                                                                        "core::option::Option::Some",
                                                                        0
                                                                      |) in
                                                                    let value :=
                                                                      M.copy (| γ0_0 |) in
                                                                    value));
                                                                fun γ =>
                                                                  ltac:(M.monadic
                                                                    (let _ :=
                                                                      M.is_struct_tuple (|
                                                                        γ,
                                                                        "core::option::Option::None"
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.never_to_any (|
                                                                        M.read (|
                                                                          M.return_ (|
                                                                            Value.StructTuple
                                                                              "core::result::Result::Err"
                                                                              [
                                                                                Value.StructRecord
                                                                                  "core::num::error::ParseIntError"
                                                                                  [
                                                                                    ("kind",
                                                                                      Value.StructTuple
                                                                                        "core::num::error::IntErrorKind::InvalidDigit"
                                                                                        [])
                                                                                  ]
                                                                              ]
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            BinOp.Wrap.sub (|
                                                              M.read (| result |),
                                                              M.rust_cast (M.read (| x |))
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ := M.use is_positive in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "u128",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "u128",
                                                                      "checked_add",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::PosOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 [] |)
                                                            |)
                                                          |)
                                                        |)))
                                                  ]
                                                |)))
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.loop (|
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ := digits 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 c := M.alloc (| γ1_0 |) in
                                                        let rest := M.alloc (| γ1_rest |) in
                                                        let~ mul :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path "u128",
                                                                "checked_mul",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| result |);
                                                                M.rust_cast (M.read (| radix |))
                                                              ]
                                                            |)
                                                          |) in
                                                        let~ x :=
                                                          M.alloc (|
                                                            M.rust_cast
                                                              (M.read (|
                                                                M.match_operator (|
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path "char",
                                                                        "to_digit",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.rust_cast
                                                                          (M.read (|
                                                                            M.read (| c |)
                                                                          |));
                                                                        M.read (| radix |)
                                                                      ]
                                                                    |)
                                                                  |),
                                                                  [
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let γ0_0 :=
                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                            γ,
                                                                            "core::option::Option::Some",
                                                                            0
                                                                          |) in
                                                                        let value :=
                                                                          M.copy (| γ0_0 |) in
                                                                        value));
                                                                    fun γ =>
                                                                      ltac:(M.monadic
                                                                        (let _ :=
                                                                          M.is_struct_tuple (|
                                                                            γ,
                                                                            "core::option::Option::None"
                                                                          |) in
                                                                        M.alloc (|
                                                                          M.never_to_any (|
                                                                            M.read (|
                                                                              M.return_ (|
                                                                                Value.StructTuple
                                                                                  "core::result::Result::Err"
                                                                                  [
                                                                                    Value.StructRecord
                                                                                      "core::num::error::ParseIntError"
                                                                                      [
                                                                                        ("kind",
                                                                                          Value.StructTuple
                                                                                            "core::num::error::IntErrorKind::InvalidDigit"
                                                                                            [])
                                                                                      ]
                                                                                  ]
                                                                              |)
                                                                            |)
                                                                          |)
                                                                        |)))
                                                                  ]
                                                                |)
                                                              |))
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                mul,
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            result,
                                                            M.read (|
                                                              M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path "u128",
                                                                      "checked_sub",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.read (| result |);
                                                                      M.read (| x |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ0_0 :=
                                                                        M.SubPointer.get_struct_tuple_field (|
                                                                          γ,
                                                                          "core::option::Option::Some",
                                                                          0
                                                                        |) in
                                                                      let value :=
                                                                        M.copy (| γ0_0 |) in
                                                                      value));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let _ :=
                                                                        M.is_struct_tuple (|
                                                                          γ,
                                                                          "core::option::Option::None"
                                                                        |) in
                                                                      M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            M.return_ (|
                                                                              Value.StructTuple
                                                                                "core::result::Result::Err"
                                                                                [
                                                                                  Value.StructRecord
                                                                                    "core::num::error::ParseIntError"
                                                                                    [
                                                                                      ("kind",
                                                                                        Value.StructTuple
                                                                                          "core::num::error::IntErrorKind::NegOverflow"
                                                                                          [])
                                                                                    ]
                                                                                ]
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)
                                                            |)
                                                          |) in
                                                        let~ _ :=
                                                          M.write (| digits, M.read (| rest |) |) 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 (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::result::Result::Ok" [ M.read (| result |) ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_u128.
  
  Module Impl_usize.
    Definition Self : Ty.t := Ty.path "usize".
    
    (*         pub const MIN: Self = 0; *)
    (* Ty.path "usize" *)
    Definition value_MIN : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.Usize 0 |))).
    
    Axiom AssociatedConstant_value_MIN : M.IsAssociatedConstant Self "value_MIN" value_MIN.
    
    (*         pub const MAX: Self = !0; *)
    (* Ty.path "usize" *)
    Definition value_MAX : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| UnOp.not (| Value.Integer IntegerKind.Usize 0 |) |))).
    
    Axiom AssociatedConstant_value_MAX : M.IsAssociatedConstant Self "value_MAX" value_MAX.
    
    (*         pub const BITS: u32 = Self::MAX.count_ones(); *)
    (* Ty.path "u32" *)
    Definition value_BITS : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "usize", "count_ones", [] |),
              [ M.read (| M.get_constant (| "core::num::MAX" |) |) ]
            |)
          |))).
    
    Axiom AssociatedConstant_value_BITS : M.IsAssociatedConstant Self "value_BITS" value_BITS.
    
    (*
            pub const fn count_ones(self) -> u32 {
                return intrinsics::ctpop(self);
            }
    *)
    Definition count_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctpop", [ Ty.path "usize" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_ones : M.IsAssociatedFunction Self "count_ones" count_ones.
    
    (*
            pub const fn count_zeros(self) -> u32 {
                (!self).count_ones()
            }
    *)
    Definition count_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "count_ones", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_count_zeros : M.IsAssociatedFunction Self "count_zeros" count_zeros.
    
    (*
            pub const fn leading_zeros(self) -> u32 {
                return intrinsics::ctlz(self as $ActualT);
            }
    *)
    Definition leading_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz", [ Ty.path "u64" ] |),
                      [ M.rust_cast (M.read (| self |)) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_zeros :
      M.IsAssociatedFunction Self "leading_zeros" leading_zeros.
    
    (*
            pub const fn trailing_zeros(self) -> u32 {
                return intrinsics::cttz(self);
            }
    *)
    Definition trailing_zeros (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::cttz", [ Ty.path "usize" ] |),
                      [ M.read (| self |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_zeros :
      M.IsAssociatedFunction Self "trailing_zeros" trailing_zeros.
    
    (*
            pub const fn leading_ones(self) -> u32 {
                (!self).leading_zeros()
            }
    *)
    Definition leading_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "leading_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_leading_ones : M.IsAssociatedFunction Self "leading_ones" leading_ones.
    
    (*
            pub const fn trailing_ones(self) -> u32 {
                (!self).trailing_zeros()
            }
    *)
    Definition trailing_ones (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "trailing_zeros", [] |),
            [ UnOp.not (| M.read (| self |) |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_trailing_ones :
      M.IsAssociatedFunction Self "trailing_ones" trailing_ones.
    
    (*
            pub const fn cast_signed(self) -> $SignedT {
                self as $SignedT
            }
    *)
    Definition cast_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast (M.read (| self |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cast_signed : M.IsAssociatedFunction Self "cast_signed" cast_signed.
    
    (*
            pub const fn rotate_left(self, n: u32) -> Self {
                return intrinsics::rotate_left(self, n);
            }
    *)
    Definition rotate_left (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_left", [ Ty.path "usize" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_left : M.IsAssociatedFunction Self "rotate_left" rotate_left.
    
    (*
            pub const fn rotate_right(self, n: u32) -> Self {
                return intrinsics::rotate_right(self, n);
            }
    *)
    Definition rotate_right (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; n ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let n := M.alloc (| n |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.never_to_any (|
                M.read (|
                  M.return_ (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::rotate_right", [ Ty.path "usize" ] |),
                      [ M.read (| self |); M.read (| n |) ]
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rotate_right : M.IsAssociatedFunction Self "rotate_right" rotate_right.
    
    (*
            pub const fn swap_bytes(self) -> Self {
                intrinsics::bswap(self as $ActualT) as Self
            }
    *)
    Definition swap_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_function (| "core::intrinsics::bswap", [ Ty.path "u64" ] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_swap_bytes : M.IsAssociatedFunction Self "swap_bytes" swap_bytes.
    
    (*
            pub const fn reverse_bits(self) -> Self {
                intrinsics::bitreverse(self as $ActualT) as Self
            }
    *)
    Definition reverse_bits (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.rust_cast
            (M.call_closure (|
              M.get_function (| "core::intrinsics::bitreverse", [ Ty.path "u64" ] |),
              [ M.rust_cast (M.read (| self |)) ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_reverse_bits : M.IsAssociatedFunction Self "reverse_bits" reverse_bits.
    
    (*
            pub const fn from_be(x: Self) -> Self {
                #[cfg(target_endian = "big")]
                {
                    x
                }
                #[cfg(not(target_endian = "big"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "swap_bytes", [] |),
            [ M.read (| x |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be : M.IsAssociatedFunction Self "from_be" from_be.
    
    (*
            pub const fn from_le(x: Self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    x
                }
                #[cfg(not(target_endian = "little"))]
                {
                    x.swap_bytes()
                }
            }
    *)
    Definition from_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (| x |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le : M.IsAssociatedFunction Self "from_le" from_le.
    
    (*
            pub const fn to_be(self) -> Self { // or not to be?
                #[cfg(target_endian = "big")]
                {
                    self
                }
                #[cfg(not(target_endian = "big"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_be (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "swap_bytes", [] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be : M.IsAssociatedFunction Self "to_be" to_be.
    
    (*
            pub const fn to_le(self) -> Self {
                #[cfg(target_endian = "little")]
                {
                    self
                }
                #[cfg(not(target_endian = "little"))]
                {
                    self.swap_bytes()
                }
            }
    *)
    Definition to_le (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| self |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le : M.IsAssociatedFunction Self "to_le" to_le.
    
    (*
            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
                // This used to use `overflowing_add`, but that means it ends up being
                // a `wrapping_add`, losing some optimization opportunities. Notably,
                // phrasing it this way helps `.checked_add(1)` optimize to a check
                // against `MAX` and a `add nuw`.
                // Per <https://github.com/rust-lang/rust/pull/124114#issuecomment-2066173305>,
                // LLVM is happy to re-form the intrinsic later if useful.
    
                if unlikely!(intrinsics::add_with_overflow(self, rhs).1) {
                    None
                } else {
                    // SAFETY: Just checked it doesn't overflow
                    Some(unsafe { intrinsics::unchecked_add(self, rhs) })
                }
            }
    *)
    Definition checked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [
                              M.read (|
                                M.SubPointer.get_tuple_field (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::intrinsics::add_with_overflow",
                                        [ Ty.path "usize" ]
                                      |),
                                      [ M.read (| self |); M.read (| rhs |) ]
                                    |)
                                  |),
                                  1
                                |)
                              |)
                            ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_add",
                              [ Ty.path "usize" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add : M.IsAssociatedFunction Self "checked_add" checked_add.
    
    (*
            pub const fn strict_add(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_add(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add : M.IsAssociatedFunction Self "strict_add" strict_add.
    
    (*
            pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_add(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_add(self, rhs)
                }
            }
    *)
    Definition unchecked_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_add",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_add", [ Ty.path "usize" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_add :
      M.IsAssociatedFunction Self "unchecked_add" unchecked_add.
    
    (*
            pub const fn checked_add_signed(self, rhs: $SignedT) -> Option<Self> {
                let (a, b) = self.overflowing_add_signed(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_add_signed :
      M.IsAssociatedFunction Self "checked_add_signed" checked_add_signed.
    
    (*
            pub const fn strict_add_signed(self, rhs: $SignedT) -> Self {
                let (a, b) = self.overflowing_add_signed(rhs);
                if b { overflow_panic::add() } else { a }
             }
    *)
    Definition strict_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_add_signed", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::add", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_add_signed :
      M.IsAssociatedFunction Self "strict_add_signed" strict_add_signed.
    
    (*
            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
                // Per PR#103299, there's no advantage to the `overflowing` intrinsic
                // for *unsigned* subtraction and we just emit the manual check anyway.
                // Thus, rather than using `overflowing_sub` that produces a wrapping
                // subtraction, check it ourself so we can use an unchecked one.
    
                if self < rhs {
                    None
                } else {
                    // SAFETY: just checked this can't overflow
                    Some(unsafe { intrinsics::unchecked_sub(self, rhs) })
                }
            }
    *)
    Definition checked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use (M.alloc (| BinOp.lt (| M.read (| self |), M.read (| rhs |) |) |)) 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_function (|
                              "core::intrinsics::unchecked_sub",
                              [ Ty.path "usize" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub : M.IsAssociatedFunction Self "checked_sub" checked_sub.
    
    (*
            pub const fn strict_sub(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_sub(rhs);
                if b { overflow_panic::sub() } else { a }
             }
    *)
    Definition strict_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::sub", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_sub : M.IsAssociatedFunction Self "strict_sub" strict_sub.
    
    (*
            pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_sub(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_sub(self, rhs)
                }
            }
    *)
    Definition unchecked_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_sub",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_sub", [ Ty.path "usize" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_sub :
      M.IsAssociatedFunction Self "unchecked_sub" unchecked_sub.
    
    (*
            pub const fn checked_signed_diff(self, rhs: Self) -> Option<$SignedT> {
                let res = self.wrapping_sub(rhs) as $SignedT;
                let overflow = (self >= rhs) == (res < 0);
    
                if !overflow {
                    Some(res)
                } else {
                    None
                }
            }
    *)
    Definition checked_signed_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ res :=
              M.alloc (|
                M.rust_cast
                  (M.call_closure (|
                    M.get_associated_function (| Ty.path "usize", "wrapping_sub", [] |),
                    [ M.read (| self |); M.read (| rhs |) ]
                  |))
              |) in
            let~ overflow :=
              M.alloc (|
                BinOp.eq (|
                  BinOp.ge (| M.read (| self |), M.read (| rhs |) |),
                  BinOp.lt (| M.read (| res |), Value.Integer IntegerKind.Isize 0 |)
                |)
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := M.use (M.alloc (| UnOp.not (| M.read (| overflow |) |) |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple "core::option::Option::Some" [ M.read (| res |) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_signed_diff :
      M.IsAssociatedFunction Self "checked_signed_diff" checked_signed_diff.
    
    (*
            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
                let (a, b) = self.overflowing_mul(rhs);
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_mul : M.IsAssociatedFunction Self "checked_mul" checked_mul.
    
    (*
            pub const fn strict_mul(self, rhs: Self) -> Self {
                let (a, b) = self.overflowing_mul(rhs);
                if b { overflow_panic::mul() } else { a }
             }
    *)
    Definition strict_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::mul", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_mul : M.IsAssociatedFunction Self "strict_mul" strict_mul.
    
    (*
            pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
                    (
                        lhs: $SelfT = self,
                        rhs: $SelfT = rhs,
                    ) => !lhs.overflowing_mul(rhs).1,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_mul(self, rhs)
                }
            }
    *)
    Definition unchecked_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_mul",
                              []
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::intrinsics::unchecked_mul", [ Ty.path "usize" ] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_mul :
      M.IsAssociatedFunction Self "unchecked_mul" unchecked_mul.
    
    (*
            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                }
            }
    *)
    Definition checked_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.Usize 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_div",
                              [ Ty.path "usize" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div : M.IsAssociatedFunction Self "checked_div" checked_div.
    
    (*
            pub const fn strict_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div : M.IsAssociatedFunction Self "strict_div" strict_div.
    
    (*
            pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.div_euclid(rhs))
                }
            }
    *)
    Definition checked_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.Usize 0 |) ]
                          |)
                        |)) 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.path "usize", "div_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_div_euclid :
      M.IsAssociatedFunction Self "checked_div_euclid" checked_div_euclid.
    
    (*
            pub const fn strict_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition strict_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_div_euclid :
      M.IsAssociatedFunction Self "strict_div_euclid" strict_div_euclid.
    
    (*
            pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    // SAFETY: div by zero has been checked above and unsigned types have no other
                    // failure modes for division
                    Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                }
            }
    *)
    Definition checked_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.Usize 0 |) ]
                          |)
                        |)) 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_function (|
                              "core::intrinsics::unchecked_rem",
                              [ Ty.path "usize" ]
                            |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem : M.IsAssociatedFunction Self "checked_rem" checked_rem.
    
    (*
            pub const fn strict_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem : M.IsAssociatedFunction Self "strict_rem" strict_rem.
    
    (*
            pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
                if unlikely!(rhs == 0) {
                    None
                } else {
                    Some(self.rem_euclid(rhs))
                }
            }
    *)
    Definition checked_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_function (| "core::intrinsics::unlikely", [] |),
                            [ BinOp.eq (| M.read (| rhs |), Value.Integer IntegerKind.Usize 0 |) ]
                          |)
                        |)) 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.path "usize", "rem_euclid", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_rem_euclid :
      M.IsAssociatedFunction Self "checked_rem_euclid" checked_rem_euclid.
    
    (*
            pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition strict_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_rem_euclid :
      M.IsAssociatedFunction Self "strict_rem_euclid" strict_rem_euclid.
    
    (*
            pub const fn ilog(self, base: Self) -> u32 {
                assert!(base >= 2, "base of integer logarithm must be at least 2");
                if let Some(log) = self.checked_ilog(base) {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            UnOp.not (|
                              BinOp.ge (| M.read (| base |), Value.Integer IntegerKind.Usize 2 |)
                            |)
                          |)) 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
                                            "base of integer logarithm must be at least 2"
                                        |)
                                      ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "usize", "checked_ilog", [] |),
                          [ M.read (| self |); M.read (| base |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog : M.IsAssociatedFunction Self "ilog" ilog.
    
    (*
            pub const fn ilog2(self) -> u32 {
                if let Some(log) = self.checked_ilog2() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "usize", "checked_ilog2", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog2 : M.IsAssociatedFunction Self "ilog2" ilog2.
    
    (*
            pub const fn ilog10(self) -> u32 {
                if let Some(log) = self.checked_ilog10() {
                    log
                } else {
                    int_log10::panic_for_nonpositive_argument()
                }
            }
    *)
    Definition ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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 γ :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "usize", "checked_ilog10", [] |),
                          [ M.read (| self |) ]
                        |)
                      |) in
                    let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let log := M.copy (| γ0_0 |) in
                    log));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (|
                            "core::num::int_log10::panic_for_nonpositive_argument",
                            []
                          |),
                          []
                        |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_ilog10 : M.IsAssociatedFunction Self "ilog10" ilog10.
    
    (*
            pub const fn checked_ilog(self, base: Self) -> Option<u32> {
                if self <= 0 || base <= 1 {
                    None
                } else if self < base {
                    Some(0)
                } else {
                    // Since base >= self, n >= 1
                    let mut n = 1;
                    let mut r = base;
    
                    // Optimization for 128 bit wide integers.
                    if Self::BITS == 128 {
                        // The following is a correct lower bound for ⌊log(base,self)⌋ because
                        //
                        // log(base,self) = log(2,self) / log(2,base)
                        //                ≥ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1)
                        //
                        // hence
                        //
                        // ⌊log(base,self)⌋ ≥ ⌊ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1) ⌋ .
                        n = self.ilog2() / (base.ilog2() + 1);
                        r = base.pow(n);
                    }
    
                    while r <= self / base {
                        n += 1;
                        r *= base;
                    }
                    Some(n)
                }
            }
    *)
    Definition checked_ilog (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; base ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let base := M.alloc (| base |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          LogicalOp.or (|
                            BinOp.le (| M.read (| self |), Value.Integer IntegerKind.Usize 0 |),
                            ltac:(M.monadic
                              (BinOp.le (| M.read (| base |), Value.Integer IntegerKind.Usize 1 |)))
                          |)
                        |)) 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 (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| base |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::option::Option::Some"
                                [ Value.Integer IntegerKind.U32 0 ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let~ n := M.alloc (| Value.Integer IntegerKind.U32 1 |) in
                            let~ r := M.copy (| base |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            BinOp.eq (|
                                              M.read (| M.get_constant (| "core::num::BITS" |) |),
                                              Value.Integer IntegerKind.U32 128
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          n,
                                          BinOp.Wrap.div (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "usize",
                                                "ilog2",
                                                []
                                              |),
                                              [ M.read (| self |) ]
                                            |),
                                            BinOp.Wrap.add (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "usize",
                                                  "ilog2",
                                                  []
                                                |),
                                                [ M.read (| base |) ]
                                              |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          r,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "usize",
                                              "pow",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| n |) ]
                                          |)
                                        |) in
                                      M.alloc (| Value.Tuple [] |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ _ :=
                              M.loop (|
                                ltac:(M.monadic
                                  (M.match_operator (|
                                    M.alloc (| Value.Tuple [] |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ :=
                                            M.use
                                              (M.alloc (|
                                                BinOp.le (|
                                                  M.read (| r |),
                                                  BinOp.Wrap.div (|
                                                    M.read (| self |),
                                                    M.read (| base |)
                                                  |)
                                                |)
                                              |)) in
                                          let _ :=
                                            M.is_constant_or_break_match (|
                                              M.read (| γ |),
                                              Value.Bool true
                                            |) in
                                          let~ _ :=
                                            let β := n in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.add (|
                                                M.read (| β |),
                                                Value.Integer IntegerKind.U32 1
                                              |)
                                            |) in
                                          let~ _ :=
                                            let β := r in
                                            M.write (|
                                              β,
                                              BinOp.Wrap.mul (| M.read (| β |), M.read (| base |) |)
                                            |) 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 (|
                              Value.StructTuple "core::option::Option::Some" [ M.read (| n |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog : M.IsAssociatedFunction Self "checked_ilog" checked_ilog.
    
    (*
            pub const fn checked_ilog2(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog2()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog2 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "core::num::nonzero::NonZero")
                                []
                                [ Ty.path "usize" ],
                              "ilog2",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog2 :
      M.IsAssociatedFunction Self "checked_ilog2" checked_ilog2.
    
    (*
            pub const fn checked_ilog10(self) -> Option<u32> {
                match NonZero::new(self) {
                    Some(x) => Some(x.ilog10()),
                    None => None,
                }
            }
    *)
    Definition checked_ilog10 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ],
                    "new",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "core::num::nonzero::NonZero")
                                []
                                [ Ty.path "usize" ],
                              "ilog10",
                              []
                            |),
                            [ M.read (| x |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_ilog10 :
      M.IsAssociatedFunction Self "checked_ilog10" checked_ilog10.
    
    (*
            pub const fn checked_neg(self) -> Option<Self> {
                let (a, b) = self.overflowing_neg();
                if unlikely!(b) { None } else { Some(a) }
            }
    *)
    Definition checked_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := 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_function (| "core::intrinsics::unlikely", [] |),
                                    [ M.read (| b |) ]
                                  |)
                                |)) 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.read (| a |) ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_neg : M.IsAssociatedFunction Self "checked_neg" checked_neg.
    
    (*
            pub const fn strict_neg(self) -> Self {
                let (a, b) = self.overflowing_neg();
                if b { overflow_panic::neg() } else { a }
            }
    *)
    Definition strict_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_neg", [] |),
                  [ M.read (| self |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::neg", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_neg : M.IsAssociatedFunction Self "strict_neg" strict_neg.
    
    (*
            pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shl as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shl(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "usize", "unchecked_shl", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shl : M.IsAssociatedFunction Self "checked_shl" checked_shl.
    
    (*
            pub const fn strict_shl(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shl(rhs);
                if b { overflow_panic::shl() } else { a }
            }
    *)
    Definition strict_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_shl", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shl", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shl : M.IsAssociatedFunction Self "strict_shl" strict_shl.
    
    (*
            pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shl(self, rhs)
                }
            }
    *)
    Definition unchecked_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shl",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shl",
                  [ Ty.path "usize"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shl :
      M.IsAssociatedFunction Self "unchecked_shl" unchecked_shl.
    
    (*
            pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shl(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "usize", "unchecked_shl", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.Usize 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shl :
      M.IsAssociatedFunction Self "unbounded_shl" unbounded_shl.
    
    (*
            pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
                // Not using overflowing_shr as that's a wrapping shift
                if rhs < Self::BITS {
                    // SAFETY: just checked the RHS is in-range
                    Some(unsafe { self.unchecked_shr(rhs) })
                } else {
                    None
                }
            }
    *)
    Definition checked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "usize", "unchecked_shr", [] |),
                            [ M.read (| self |); M.read (| rhs |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_shr : M.IsAssociatedFunction Self "checked_shr" checked_shr.
    
    (*
            pub const fn strict_shr(self, rhs: u32) -> Self {
                let (a, b) = self.overflowing_shr(rhs);
                if b { overflow_panic::shr() } else { a }
            }
    *)
    Definition strict_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_shr", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ := M.use b 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::num::overflow_panic::shr", [] |),
                                  []
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic a)
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_shr : M.IsAssociatedFunction Self "strict_shr" strict_shr.
    
    (*
            pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
                assert_unsafe_precondition!(
                    check_language_ub,
                    concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
                    (
                        rhs: u32 = rhs,
                    ) => rhs < <$ActualT>::BITS,
                );
    
                // SAFETY: this is guaranteed to be safe by the caller.
                unsafe {
                    intrinsics::unchecked_shr(self, rhs)
                }
            }
    *)
    Definition unchecked_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) 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.unchecked_shr",
                              []
                            |),
                            [ M.read (| rhs |) ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (|
                  "core::intrinsics::unchecked_shr",
                  [ Ty.path "usize"; Ty.path "u32" ]
                |),
                [ M.read (| self |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unchecked_shr :
      M.IsAssociatedFunction Self "unchecked_shr" unchecked_shr.
    
    (*
            pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
                if rhs < Self::BITS {
                    // SAFETY:
                    // rhs is just checked to be in-range above
                    unsafe { self.unchecked_shr(rhs) }
                } else {
                    0
                }
            }
    *)
    Definition unbounded_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.lt (|
                            M.read (| rhs |),
                            M.read (| M.get_constant (| "core::num::BITS" |) |)
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "usize", "unchecked_shr", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.Usize 0 |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_unbounded_shr :
      M.IsAssociatedFunction Self "unbounded_shr" unbounded_shr.
    
    (*
            pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
                if exp == 0 {
                    return Some(1);
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = try_opt!(acc.checked_mul(base));
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return Some(acc);
                        }
                    }
                    exp /= 2;
                    base = try_opt!(base.checked_mul(base));
                }
            }
    *)
    Definition checked_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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::Some"
                                    [ Value.Integer IntegerKind.Usize 1 ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "usize",
                                                  "checked_mul",
                                                  []
                                                |),
                                                [ M.read (| acc |); M.read (| base |) ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let x := M.copy (| γ0_0 |) in
                                                  x));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let _ :=
                                                    M.is_struct_tuple (|
                                                      γ,
                                                      "core::option::Option::None"
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::option::Option::None"
                                                            []
                                                        |)
                                                      |)
                                                    |)
                                                  |)))
                                            ]
                                          |)
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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.StructTuple
                                                      "core::option::Option::Some"
                                                      [ M.read (| acc |) ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "usize",
                                        "checked_mul",
                                        []
                                      |),
                                      [ M.read (| base |); M.read (| base |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let x := M.copy (| γ0_0 |) in
                                        x));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                Value.StructTuple "core::option::Option::None" []
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_pow : M.IsAssociatedFunction Self "checked_pow" checked_pow.
    
    (*
            pub const fn strict_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                loop {
                    if (exp & 1) == 1 {
                        acc = acc.strict_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            return acc;
                        }
                    }
                    exp /= 2;
                    base = base.strict_mul(base);
                }
            }
    *)
    Definition strict_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.Usize 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "usize",
                                            "strict_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    M.read (| exp |),
                                                    Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "usize", "strict_mul", [] |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_strict_pow : M.IsAssociatedFunction Self "strict_pow" strict_pow.
    
    (*
            pub const fn saturating_add(self, rhs: Self) -> Self {
                intrinsics::saturating_add(self, rhs)
            }
    *)
    Definition saturating_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_add", [ Ty.path "usize" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add :
      M.IsAssociatedFunction Self "saturating_add" saturating_add.
    
    (*
            pub const fn saturating_add_signed(self, rhs: $SignedT) -> Self {
                let (res, overflow) = self.overflowing_add(rhs as Self);
                if overflow == (rhs < 0) {
                    res
                } else if overflow {
                    Self::MAX
                } else {
                    0
                }
            }
    *)
    Definition saturating_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflow := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| overflow |),
                                    BinOp.lt (|
                                      M.read (| rhs |),
                                      Value.Integer IntegerKind.Isize 0
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            res));
                        fun γ =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ := M.use overflow in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.get_constant (| "core::num::MAX" |)));
                                fun γ =>
                                  ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.Usize 0 |)))
                              ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_add_signed :
      M.IsAssociatedFunction Self "saturating_add_signed" saturating_add_signed.
    
    (*
            pub const fn saturating_sub(self, rhs: Self) -> Self {
                intrinsics::saturating_sub(self, rhs)
            }
    *)
    Definition saturating_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::saturating_sub", [ Ty.path "usize" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      M.IsAssociatedFunction Self "saturating_sub" saturating_sub.
    
    (*
            pub const fn saturating_mul(self, rhs: Self) -> Self {
                match self.checked_mul(rhs) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "checked_mul", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_mul :
      M.IsAssociatedFunction Self "saturating_mul" saturating_mul.
    
    (*
            pub const fn saturating_div(self, rhs: Self) -> Self {
                // on unsigned types, there is no overflow in integer division
                self.wrapping_div(rhs)
            }
    *)
    Definition saturating_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "wrapping_div", [] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_div :
      M.IsAssociatedFunction Self "saturating_div" saturating_div.
    
    (*
            pub const fn saturating_pow(self, exp: u32) -> Self {
                match self.checked_pow(exp) {
                    Some(x) => x,
                    None => Self::MAX,
                }
            }
    *)
    Definition saturating_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "checked_pow", [] |),
                  [ M.read (| self |); M.read (| exp |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (|
                        γ,
                        "core::option::Option::Some",
                        0
                      |) in
                    let x := M.copy (| γ0_0 |) in
                    x));
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                    M.get_constant (| "core::num::MAX" |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_pow :
      M.IsAssociatedFunction Self "saturating_pow" saturating_pow.
    
    (*
            pub const fn wrapping_add(self, rhs: Self) -> Self {
                intrinsics::wrapping_add(self, rhs)
            }
    *)
    Definition wrapping_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_add", [ Ty.path "usize" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add : M.IsAssociatedFunction Self "wrapping_add" wrapping_add.
    
    (*
            pub const fn wrapping_add_signed(self, rhs: $SignedT) -> Self {
                self.wrapping_add(rhs as Self)
            }
    *)
    Definition wrapping_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "wrapping_add", [] |),
            [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_add_signed :
      M.IsAssociatedFunction Self "wrapping_add_signed" wrapping_add_signed.
    
    (*
            pub const fn wrapping_sub(self, rhs: Self) -> Self {
                intrinsics::wrapping_sub(self, rhs)
            }
    *)
    Definition wrapping_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_sub", [ Ty.path "usize" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_sub : M.IsAssociatedFunction Self "wrapping_sub" wrapping_sub.
    
    (*
            pub const fn wrapping_mul(self, rhs: Self) -> Self {
                intrinsics::wrapping_mul(self, rhs)
            }
    *)
    Definition wrapping_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::wrapping_mul", [ Ty.path "usize" ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_mul : M.IsAssociatedFunction Self "wrapping_mul" wrapping_mul.
    
    (*
            pub const fn wrapping_div(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div : M.IsAssociatedFunction Self "wrapping_div" wrapping_div.
    
    (*
            pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition wrapping_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_div_euclid :
      M.IsAssociatedFunction Self "wrapping_div_euclid" wrapping_div_euclid.
    
    (*
            pub const fn wrapping_rem(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem : M.IsAssociatedFunction Self "wrapping_rem" wrapping_rem.
    
    (*
            pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition wrapping_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_rem_euclid :
      M.IsAssociatedFunction Self "wrapping_rem_euclid" wrapping_rem_euclid.
    
    (*
            pub const fn wrapping_neg(self) -> Self {
                (0 as $SelfT).wrapping_sub(self)
            }
    *)
    Definition wrapping_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "wrapping_sub", [] |),
            [
              M.read (| M.use (M.alloc (| Value.Integer IntegerKind.Usize 0 |)) |);
              M.read (| self |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_neg : M.IsAssociatedFunction Self "wrapping_neg" wrapping_neg.
    
    (*
            pub const fn wrapping_shl(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shl(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "unchecked_shl", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shl : M.IsAssociatedFunction Self "wrapping_shl" wrapping_shl.
    
    (*
            pub const fn wrapping_shr(self, rhs: u32) -> Self {
                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
                // out of bounds
                unsafe {
                    self.unchecked_shr(rhs & (Self::BITS - 1))
                }
            }
    *)
    Definition wrapping_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "unchecked_shr", [] |),
            [
              M.read (| self |);
              BinOp.bit_and
                (M.read (| rhs |))
                (BinOp.Wrap.sub (|
                  M.read (| M.get_constant (| "core::num::BITS" |) |),
                  Value.Integer IntegerKind.U32 1
                |))
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_shr : M.IsAssociatedFunction Self "wrapping_shr" wrapping_shr.
    
    (*
            pub const fn wrapping_pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc: Self = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary.
                    acc.wrapping_mul(base)
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc.wrapping_mul(base);
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base.wrapping_mul(base);
                    }
                }
            }
    *)
    Definition wrapping_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.Usize 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "usize",
                                                        "wrapping_mul",
                                                        []
                                                      |),
                                                      [ M.read (| acc |); M.read (| base |) ]
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "usize",
                                              "wrapping_mul",
                                              []
                                            |),
                                            [ M.read (| base |); M.read (| base |) ]
                                          |)
                                        |) 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.path "usize", "wrapping_mul", [] |),
                            [ M.read (| acc |); M.read (| base |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "usize",
                                                    "wrapping_mul",
                                                    []
                                                  |),
                                                  [ M.read (| acc |); M.read (| base |) ]
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "usize",
                                          "wrapping_mul",
                                          []
                                        |),
                                        [ M.read (| base |); M.read (| base |) ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_pow : M.IsAssociatedFunction Self "wrapping_pow" wrapping_pow.
    
    (*
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::add_with_overflow", [ Ty.path "u64" ] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.rust_cast (M.read (| a |)); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add :
      M.IsAssociatedFunction Self "overflowing_add" overflowing_add.
    
    (*
            pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_add(rhs);
                let (c, d) = a.overflowing_add(carry as $SelfT);
                (c, b || d)
            }
    *)
    Definition carrying_add (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_add", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "usize", "overflowing_add", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| carry |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_add : M.IsAssociatedFunction Self "carrying_add" carrying_add.
    
    (*
            pub const fn overflowing_add_signed(self, rhs: $SignedT) -> (Self, bool) {
                let (res, overflowed) = self.overflowing_add(rhs as Self);
                (res, overflowed ^ (rhs < 0))
            }
    *)
    Definition overflowing_add_signed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_add", [] |),
                  [ M.read (| self |); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 res := M.copy (| γ0_0 |) in
                    let overflowed := M.copy (| γ0_1 |) in
                    M.alloc (|
                      Value.Tuple
                        [
                          M.read (| res |);
                          BinOp.bit_xor
                            (M.read (| overflowed |))
                            (BinOp.lt (| M.read (| rhs |), Value.Integer IntegerKind.Isize 0 |))
                        ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_add_signed :
      M.IsAssociatedFunction Self "overflowing_add_signed" overflowing_add_signed.
    
    (*
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::sub_with_overflow", [ Ty.path "u64" ] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.rust_cast (M.read (| a |)); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_sub :
      M.IsAssociatedFunction Self "overflowing_sub" overflowing_sub.
    
    (*
            pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
                // note: longer-term this should be done via an intrinsic, but this has been shown
                //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
                let (a, b) = self.overflowing_sub(rhs);
                let (c, d) = a.overflowing_sub(borrow as $SelfT);
                (c, b || d)
            }
    *)
    Definition borrowing_sub (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; borrow ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let borrow := M.alloc (| borrow |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "usize", "overflowing_sub", [] |),
                  [ M.read (| self |); M.read (| rhs |) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (| Ty.path "usize", "overflowing_sub", [] |),
                          [ M.read (| a |); M.rust_cast (M.read (| borrow |)) ]
                        |)
                      |),
                      [
                        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 c := M.copy (| γ0_0 |) in
                            let d := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.Tuple
                                [
                                  M.read (| c |);
                                  LogicalOp.or (|
                                    M.read (| b |),
                                    ltac:(M.monadic (M.read (| d |)))
                                  |)
                                ]
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_borrowing_sub :
      M.IsAssociatedFunction Self "borrowing_sub" borrowing_sub.
    
    (*
            pub const fn abs_diff(self, other: Self) -> Self {
                if mem::size_of::<Self>() == 1 {
                    // Trick LLVM into generating the psadbw instruction when SSE2
                    // is available and this function is autovectorized for u8's.
                    (self as i32).wrapping_sub(other as i32).abs() as Self
                } else {
                    if self < other {
                        other - self
                    } else {
                        self - other
                    }
                }
            }
    *)
    Definition abs_diff (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.eq (|
                            M.call_closure (|
                              M.get_function (| "core::mem::size_of", [ Ty.path "usize" ] |),
                              []
                            |),
                            Value.Integer IntegerKind.Usize 1
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      M.rust_cast
                        (M.call_closure (|
                          M.get_associated_function (| Ty.path "i32", "abs", [] |),
                          [
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "i32", "wrapping_sub", [] |),
                              [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| other |)) ]
                            |)
                          ]
                        |))
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (| M.read (| self |), M.read (| other |) |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              BinOp.Wrap.sub (| M.read (| other |), M.read (| self |) |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (M.alloc (|
                              BinOp.Wrap.sub (| M.read (| self |), M.read (| other |) |)
                            |)))
                      ]
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_abs_diff : M.IsAssociatedFunction Self "abs_diff" abs_diff.
    
    (*
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                (a as Self, b)
            }
    *)
    Definition overflowing_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "core::intrinsics::mul_with_overflow", [ Ty.path "u64" ] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |),
              [
                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 a := M.copy (| γ0_0 |) in
                    let b := M.copy (| γ0_1 |) in
                    M.alloc (| Value.Tuple [ M.rust_cast (M.read (| a |)); M.read (| b |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_mul :
      M.IsAssociatedFunction Self "overflowing_mul" overflowing_mul.
    
    (*
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div :
      M.IsAssociatedFunction Self "overflowing_div" overflowing_div.
    
    (*
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
                (self / rhs, false)
            }
    *)
    Definition overflowing_div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_div_euclid :
      M.IsAssociatedFunction Self "overflowing_div_euclid" overflowing_div_euclid.
    
    (*
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem :
      M.IsAssociatedFunction Self "overflowing_rem" overflowing_rem.
    
    (*
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
                (self % rhs, false)
            }
    *)
    Definition overflowing_rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [ BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |); Value.Bool false ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_rem_euclid :
      M.IsAssociatedFunction Self "overflowing_rem_euclid" overflowing_rem_euclid.
    
    (*
            pub const fn overflowing_neg(self) -> (Self, bool) {
                ((!self).wrapping_add(1), self != 0)
            }
    *)
    Definition overflowing_neg (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "usize", "wrapping_add", [] |),
                [ UnOp.not (| M.read (| self |) |); Value.Integer IntegerKind.Usize 1 ]
              |);
              BinOp.ne (| M.read (| self |), Value.Integer IntegerKind.Usize 0 |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_neg :
      M.IsAssociatedFunction Self "overflowing_neg" overflowing_neg.
    
    (*
            pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shl(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "usize", "wrapping_shl", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shl :
      M.IsAssociatedFunction Self "overflowing_shl" overflowing_shl.
    
    (*
            pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                (self.wrapping_shr(rhs), rhs >= Self::BITS)
            }
    *)
    Definition overflowing_shr (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          Value.Tuple
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "usize", "wrapping_shr", [] |),
                [ M.read (| self |); M.read (| rhs |) ]
              |);
              BinOp.ge (| M.read (| rhs |), M.read (| M.get_constant (| "core::num::BITS" |) |) |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_shr :
      M.IsAssociatedFunction Self "overflowing_shr" overflowing_shr.
    
    (*
            pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
                if exp == 0{
                    return (1,false);
                }
                let mut base = self;
                let mut acc: Self = 1;
                let mut overflown = false;
                // Scratch space for storing results of overflowing_mul.
                let mut r;
    
                loop {
                    if (exp & 1) == 1 {
                        r = acc.overflowing_mul(base);
                        // since exp!=0, finally the exp must be 1.
                        if exp == 1 {
                            r.1 |= overflown;
                            return r;
                        }
                        acc = r.0;
                        overflown |= r.1;
                    }
                    exp /= 2;
                    r = base.overflowing_mul(base);
                    base = r.0;
                    overflown |= r.1;
                }
            }
    *)
    Definition overflowing_pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Tuple
                                    [ Value.Integer IntegerKind.Usize 1; Value.Bool false ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
                let~ overflown := M.alloc (| Value.Bool false |) in
                let~ r := M.copy (| Value.DeclaredButUndefined |) in
                M.alloc (|
                  M.never_to_any (|
                    M.read (|
                      M.loop (|
                        ltac:(M.monadic
                          (let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            BinOp.bit_and
                                              (M.read (| exp |))
                                              (Value.Integer IntegerKind.U32 1),
                                            Value.Integer IntegerKind.U32 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        r,
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "usize",
                                            "overflowing_mul",
                                            []
                                          |),
                                          [ M.read (| acc |); M.read (| base |) ]
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (|
                                                      M.read (| exp |),
                                                      Value.Integer IntegerKind.U32 1
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_tuple_field (| r, 1 |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.bit_or
                                                          (M.read (| β |))
                                                          (M.read (| overflown |))
                                                      |) in
                                                    M.return_ (| M.read (| r |) |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        acc,
                                        M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                                      |) in
                                    let~ _ :=
                                      let β := overflown in
                                      M.write (|
                                        β,
                                        BinOp.bit_or
                                          (M.read (| β |))
                                          (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            let β := exp in
                            M.write (|
                              β,
                              BinOp.Wrap.div (| M.read (| β |), Value.Integer IntegerKind.U32 2 |)
                            |) in
                          let~ _ :=
                            M.write (|
                              r,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "usize",
                                  "overflowing_mul",
                                  []
                                |),
                                [ M.read (| base |); M.read (| base |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              base,
                              M.read (| M.SubPointer.get_tuple_field (| r, 0 |) |)
                            |) in
                          let~ _ :=
                            let β := overflown in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.read (| M.SubPointer.get_tuple_field (| r, 1 |) |))
                            |) in
                          M.alloc (| Value.Tuple [] |)))
                      |)
                    |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_overflowing_pow :
      M.IsAssociatedFunction Self "overflowing_pow" overflowing_pow.
    
    (*
            pub const fn pow(self, mut exp: u32) -> Self {
                if exp == 0 {
                    return 1;
                }
                let mut base = self;
                let mut acc = 1;
    
                if intrinsics::is_val_statically_known(exp) {
                    while exp > 1 {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                        }
                        exp /= 2;
                        base = base * base;
                    }
    
                    // since exp!=0, finally the exp must be 1.
                    // Deal with the final bit of the exponent separately, since
                    // squaring the base afterwards is not necessary and may cause a
                    // needless overflow.
                    acc * base
                } else {
                    // This is faster than the above when the exponent is not known
                    // at compile time. We can't use the same code for the constant
                    // exponent case because LLVM is currently unable to unroll
                    // this loop.
                    loop {
                        if (exp & 1) == 1 {
                            acc = acc * base;
                            // since exp!=0, finally the exp must be 1.
                            if exp == 1 {
                                return acc;
                            }
                        }
                        exp /= 2;
                        base = base * base;
                    }
                }
            }
    *)
    Definition pow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; exp ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let exp := M.alloc (| exp |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (| M.read (| exp |), Value.Integer IntegerKind.U32 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.Integer IntegerKind.Usize 1 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ base := M.copy (| self |) in
                let~ acc := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              M.call_closure (|
                                M.get_function (|
                                  "core::intrinsics::is_val_statically_known",
                                  [ Ty.path "u32" ]
                                |),
                                [ M.read (| exp |) ]
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) 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 (| exp |),
                                              Value.Integer IntegerKind.U32 1
                                            |)
                                          |)) 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.eq (|
                                                        BinOp.bit_and
                                                          (M.read (| exp |))
                                                          (Value.Integer IntegerKind.U32 1),
                                                        Value.Integer IntegerKind.U32 1
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  M.write (|
                                                    acc,
                                                    BinOp.Wrap.mul (|
                                                      M.read (| acc |),
                                                      M.read (| base |)
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      let~ _ :=
                                        let β := exp in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.div (|
                                            M.read (| β |),
                                            Value.Integer IntegerKind.U32 2
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          base,
                                          BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                        |) 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 (| BinOp.Wrap.mul (| M.read (| acc |), M.read (| base |) |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          M.never_to_any (|
                            M.read (|
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (|
                                                    BinOp.bit_and
                                                      (M.read (| exp |))
                                                      (Value.Integer IntegerKind.U32 1),
                                                    Value.Integer IntegerKind.U32 1
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                acc,
                                                BinOp.Wrap.mul (|
                                                  M.read (| acc |),
                                                  M.read (| base |)
                                                |)
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            M.read (| exp |),
                                                            Value.Integer IntegerKind.U32 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_ (| M.read (| acc |) |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  let~ _ :=
                                    let β := exp in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.div (|
                                        M.read (| β |),
                                        Value.Integer IntegerKind.U32 2
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      base,
                                      BinOp.Wrap.mul (| M.read (| base |), M.read (| base |) |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)
                            |)
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_pow : M.IsAssociatedFunction Self "pow" pow.
    
    (*
            pub const fn isqrt(self) -> Self {
                let result = crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
    
                // Inform the optimizer what the range of outputs is. If testing
                // `core` crashes with no panic message and a `num::int_sqrt::u*`
                // test failed, it's because your edits caused these assertions or
                // the assertions in `fn isqrt` of `nonzero.rs` to become false.
                //
                // SAFETY: Integer square root is a monotonically nondecreasing
                // function, which means that increasing the input will never
                // cause the output to decrease. Thus, since the input for unsigned
                // integers is bounded by `[0, <$ActualT>::MAX]`, sqrt(n) will be
                // bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
                unsafe {
                    const MAX_RESULT: $SelfT = crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
                    crate::hint::assert_unchecked(result <= MAX_RESULT);
                }
    
                result
            }
    *)
    Definition isqrt (ε : 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~ result :=
              M.alloc (|
                M.rust_cast
                  (M.call_closure (|
                    M.get_function (| "core::num::int_sqrt::u64", [] |),
                    [ M.rust_cast (M.read (| self |)) ]
                  |))
              |) in
            let~ _ :=
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (| "core::hint::assert_unchecked", [] |),
                    [
                      BinOp.le (|
                        M.read (| result |),
                        M.read (| M.get_constant (| "core::num::isqrt::MAX_RESULT" |) |)
                      |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |) in
            result
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_isqrt : M.IsAssociatedFunction Self "isqrt" isqrt.
    
    (*
            pub const fn div_euclid(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_euclid : M.IsAssociatedFunction Self "div_euclid" div_euclid.
    
    (*
            pub const fn rem_euclid(self, rhs: Self) -> Self {
                self % rhs
            }
    *)
    Definition rem_euclid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_rem_euclid : M.IsAssociatedFunction Self "rem_euclid" rem_euclid.
    
    (*
            pub const fn div_floor(self, rhs: Self) -> Self {
                self / rhs
            }
    *)
    Definition div_floor (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_floor : M.IsAssociatedFunction Self "div_floor" div_floor.
    
    (*
            pub const fn div_ceil(self, rhs: Self) -> Self {
                let d = self / rhs;
                let r = self % rhs;
                if r > 0 {
                    d + 1
                } else {
                    d
                }
            }
    *)
    Definition div_ceil (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ d := M.alloc (| BinOp.Wrap.div (| M.read (| self |), M.read (| rhs |) |) |) in
            let~ r := M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |) in
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          BinOp.gt (| M.read (| r |), Value.Integer IntegerKind.Usize 0 |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      BinOp.Wrap.add (| M.read (| d |), Value.Integer IntegerKind.Usize 1 |)
                    |)));
                fun γ => ltac:(M.monadic d)
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_div_ceil : M.IsAssociatedFunction Self "div_ceil" div_ceil.
    
    (*
            pub const fn next_multiple_of(self, rhs: Self) -> Self {
                match self % rhs {
                    0 => self,
                    r => self + (rhs - r)
                }
            }
    *)
    Definition next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              M.alloc (| BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |) |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.Usize 0
                      |) in
                    self));
                fun γ =>
                  ltac:(M.monadic
                    (let r := M.copy (| γ |) in
                    M.alloc (|
                      BinOp.Wrap.add (|
                        M.read (| self |),
                        BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_multiple_of :
      M.IsAssociatedFunction Self "next_multiple_of" next_multiple_of.
    
    (*
            pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
                match try_opt!(self.checked_rem(rhs)) {
                    0 => Some(self),
                    // rhs - r cannot overflow because r is smaller than rhs
                    r => self.checked_add(rhs - r)
                }
            }
    *)
    Definition checked_next_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                M.match_operator (|
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "usize", "checked_rem", [] |),
                        [ M.read (| self |); M.read (| rhs |) ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let x := M.copy (| γ0_0 |) in
                          x));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.return_ (| Value.StructTuple "core::option::Option::None" [] |)
                              |)
                            |)
                          |)))
                    ]
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let _ :=
                          M.is_constant_or_break_match (|
                            M.read (| γ |),
                            Value.Integer IntegerKind.Usize 0
                          |) in
                        M.alloc (|
                          Value.StructTuple "core::option::Option::Some" [ M.read (| self |) ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let r := M.copy (| γ |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "usize", "checked_add", [] |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.sub (| M.read (| rhs |), M.read (| r |) |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_multiple_of :
      M.IsAssociatedFunction Self "checked_next_multiple_of" checked_next_multiple_of.
    
    (*
            pub const fn is_multiple_of(self, rhs: Self) -> bool {
                match rhs {
                    0 => self == 0,
                    _ => self % rhs == 0,
                }
            }
    *)
    Definition is_multiple_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.match_operator (|
              rhs,
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ :=
                      M.is_constant_or_break_match (|
                        M.read (| γ |),
                        Value.Integer IntegerKind.Usize 0
                      |) in
                    M.alloc (|
                      BinOp.eq (| M.read (| self |), Value.Integer IntegerKind.Usize 0 |)
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (M.alloc (|
                      BinOp.eq (|
                        BinOp.Wrap.rem (| M.read (| self |), M.read (| rhs |) |),
                        Value.Integer IntegerKind.Usize 0
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_multiple_of :
      M.IsAssociatedFunction Self "is_multiple_of" is_multiple_of.
    
    (*
            pub const fn is_power_of_two(self) -> bool {
                self.count_ones() == 1
            }
    *)
    Definition is_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.eq (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "usize", "count_ones", [] |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.U32 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_power_of_two :
      M.IsAssociatedFunction Self "is_power_of_two" is_power_of_two.
    
    (*
            const fn one_less_than_next_power_of_two(self) -> Self {
                if self <= 1 { return 0; }
    
                let p = self - 1;
                // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros.
                // That means the shift is always in-bounds, and some processors
                // (such as intel pre-haswell) have more efficient ctlz
                // intrinsics when the argument is non-zero.
                let z = unsafe { intrinsics::ctlz_nonzero(p) };
                <$SelfT>::MAX >> z
            }
    *)
    Definition one_less_than_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ 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 (|
                                BinOp.le (| M.read (| self |), 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.Integer IntegerKind.Usize 0 |) |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ p :=
                  M.alloc (|
                    BinOp.Wrap.sub (| M.read (| self |), Value.Integer IntegerKind.Usize 1 |)
                  |) in
                let~ z :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::ctlz_nonzero", [ Ty.path "usize" ] |),
                      [ M.read (| p |) ]
                    |)
                  |) in
                M.alloc (|
                  BinOp.Wrap.shr (|
                    M.read (| M.get_constant (| "core::num::MAX" |) |),
                    M.read (| z |)
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_one_less_than_next_power_of_two :
      M.IsAssociatedFunction Self "one_less_than_next_power_of_two" one_less_than_next_power_of_two.
    
    (*
            pub const fn next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two() + 1
            }
    *)
    Definition next_power_of_two (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.Wrap.add (|
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "usize",
                "one_less_than_next_power_of_two",
                []
              |),
              [ M.read (| self |) ]
            |),
            Value.Integer IntegerKind.Usize 1
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_next_power_of_two :
      M.IsAssociatedFunction Self "next_power_of_two" next_power_of_two.
    
    (*
            pub const fn checked_next_power_of_two(self) -> Option<Self> {
                self.one_less_than_next_power_of_two().checked_add(1)
            }
    *)
    Definition checked_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "checked_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "usize",
                  "one_less_than_next_power_of_two",
                  []
                |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.Usize 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_next_power_of_two :
      M.IsAssociatedFunction Self "checked_next_power_of_two" checked_next_power_of_two.
    
    (*
            pub const fn wrapping_next_power_of_two(self) -> Self {
                self.one_less_than_next_power_of_two().wrapping_add(1)
            }
    *)
    Definition wrapping_next_power_of_two
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "wrapping_add", [] |),
            [
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "usize",
                  "one_less_than_next_power_of_two",
                  []
                |),
                [ M.read (| self |) ]
              |);
              Value.Integer IntegerKind.Usize 1
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_wrapping_next_power_of_two :
      M.IsAssociatedFunction Self "wrapping_next_power_of_two" wrapping_next_power_of_two.
    
    (*
            pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_be().to_ne_bytes()
            }
    *)
    Definition to_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "usize", "to_be", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_be_bytes : M.IsAssociatedFunction Self "to_be_bytes" to_be_bytes.
    
    (*
            pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
                self.to_le().to_ne_bytes()
            }
    *)
    Definition to_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "to_ne_bytes", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "usize", "to_le", [] |),
                [ M.read (| self |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_le_bytes : M.IsAssociatedFunction Self "to_le_bytes" to_le_bytes.
    
    (*
            pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
                // SAFETY: integers are plain old datatypes so we can always transmute them to
                // arrays of bytes
                unsafe { mem::transmute(self) }
            }
    *)
    Definition to_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.path "usize";
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 8 ] [ Ty.path "u8" ]
              ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_ne_bytes : M.IsAssociatedFunction Self "to_ne_bytes" to_ne_bytes.
    
    (*
            pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_be(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_be_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "from_be", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "usize", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_be_bytes :
      M.IsAssociatedFunction Self "from_be_bytes" from_be_bytes.
    
    (*
            pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                Self::from_le(Self::from_ne_bytes(bytes))
            }
    *)
    Definition from_le_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "from_le", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "usize", "from_ne_bytes", [] |),
                [ M.read (| bytes |) ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_le_bytes :
      M.IsAssociatedFunction Self "from_le_bytes" from_le_bytes.
    
    (*
            pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
                // SAFETY: integers are plain old datatypes so we can always transmute to them
                unsafe { mem::transmute(bytes) }
            }
    *)
    Definition from_ne_bytes (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ bytes ] =>
        ltac:(M.monadic
          (let bytes := M.alloc (| bytes |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::transmute",
              [
                Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 8 ] [ Ty.path "u8" ];
                Ty.path "usize"
              ]
            |),
            [ M.read (| bytes |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_ne_bytes :
      M.IsAssociatedFunction Self "from_ne_bytes" from_ne_bytes.
    
    (*         pub const fn min_value() -> Self { Self::MIN } *)
    Definition min_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MIN" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_min_value : M.IsAssociatedFunction Self "min_value" min_value.
    
    (*         pub const fn max_value() -> Self { Self::MAX } *)
    Definition max_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] => ltac:(M.monadic (M.read (| M.get_constant (| "core::num::MAX" |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_max_value : M.IsAssociatedFunction Self "max_value" max_value.
    
    (*
            pub const fn widening_mul(self, rhs: Self) -> (Self, Self) {
                // note: longer-term this should be done via an intrinsic,
                //   but for now we can deal without an impl for u128/i128
                // SAFETY: overflow will be contained within the wider types
                let wide = unsafe { (self as $WideT).unchecked_mul(rhs as $WideT) };
                (wide as $SelfT, (wide >> $BITS) as $SelfT)
            }
    *)
    Definition widening_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            let~ wide :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "unchecked_mul", [] |),
                  [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.rust_cast (M.read (| wide |));
                  M.rust_cast
                    (BinOp.Wrap.shr (| M.read (| wide |), Value.Integer IntegerKind.I32 64 |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_widening_mul : M.IsAssociatedFunction Self "widening_mul" widening_mul.
    
    (*
            pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
                // note: longer-term this should be done via an intrinsic,
                //   but for now we can deal without an impl for u128/i128
                // SAFETY: overflow will be contained within the wider types
                let wide = unsafe {
                    (self as $WideT).unchecked_mul(rhs as $WideT).unchecked_add(carry as $WideT)
                };
                (wide as $SelfT, (wide >> $BITS) as $SelfT)
            }
    *)
    Definition carrying_mul (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs; carry ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          let carry := M.alloc (| carry |) in
          M.read (|
            let~ wide :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u128", "unchecked_add", [] |),
                  [
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "u128", "unchecked_mul", [] |),
                      [ M.rust_cast (M.read (| self |)); M.rust_cast (M.read (| rhs |)) ]
                    |);
                    M.rust_cast (M.read (| carry |))
                  ]
                |)
              |) in
            M.alloc (|
              Value.Tuple
                [
                  M.rust_cast (M.read (| wide |));
                  M.rust_cast
                    (BinOp.Wrap.shr (| M.read (| wide |), Value.Integer IntegerKind.I32 64 |))
                ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_carrying_mul : M.IsAssociatedFunction Self "carrying_mul" carrying_mul.
    
    (*
            pub const fn midpoint(self, rhs: $SelfT) -> $SelfT {
                ((self as $WideT + rhs as $WideT) / 2) as $SelfT
            }
    *)
    Definition midpoint (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.rust_cast
            (BinOp.Wrap.div (|
              BinOp.Wrap.add (| M.rust_cast (M.read (| self |)), M.rust_cast (M.read (| rhs |)) |),
              Value.Integer IntegerKind.U128 2
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_midpoint : M.IsAssociatedFunction Self "midpoint" midpoint.
    (*
        pub(crate) const fn repeat_u8(x: u8) -> usize {
            usize::from_ne_bytes([x; mem::size_of::<usize>()])
        }
    *)
    Definition repeat_u8 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "from_ne_bytes", [] |),
            [ repeat (| M.read (| x |), Value.Integer IntegerKind.Usize 8 |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_repeat_u8 : M.IsAssociatedFunction Self "repeat_u8" repeat_u8.
    
    (*
        pub(crate) const fn repeat_u16(x: u16) -> usize {
            let mut r = 0usize;
            let mut i = 0;
            while i < mem::size_of::<usize>() {
                // Use `wrapping_shl` to make it work on targets with 16-bit `usize`
                r = r.wrapping_shl(16) | (x as usize);
                i += 2;
            }
            r
        }
    *)
    Definition repeat_u16 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          M.read (|
            let~ r := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
            let~ i := 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.lt (|
                                  M.read (| i |),
                                  M.call_closure (|
                                    M.get_function (| "core::mem::size_of", [ Ty.path "usize" ] |),
                                    []
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.write (|
                              r,
                              BinOp.bit_or
                                (M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "usize",
                                    "wrapping_shl",
                                    []
                                  |),
                                  [ M.read (| r |); Value.Integer IntegerKind.U32 16 ]
                                |))
                                (M.rust_cast (M.read (| x |)))
                            |) in
                          let~ _ :=
                            let β := i in
                            M.write (|
                              β,
                              BinOp.Wrap.add (| M.read (| β |), Value.Integer IntegerKind.Usize 2 |)
                            |) 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
            r
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_repeat_u16 : M.IsAssociatedFunction Self "repeat_u16" repeat_u16.
    (*
            pub const fn from_str_radix(src: &str, radix: u32) -> Result<$size, ParseIntError> {
                match <$t>::from_str_radix(src, radix) {
                    Ok(x) => Ok(x as $size),
                    Err(e) => Err(e),
                }
            }
    *)
    Definition from_str_radix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src; radix ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          let radix := M.alloc (| radix |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "u64", "from_str_radix", [] |),
                  [ M.read (| src |); M.read (| radix |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (| γ, "core::result::Result::Ok", 0 |) in
                    let x := M.copy (| γ0_0 |) in
                    M.alloc (|
                      Value.StructTuple "core::result::Result::Ok" [ M.rust_cast (M.read (| x |)) ]
                    |)));
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 :=
                      M.SubPointer.get_struct_tuple_field (| γ, "core::result::Result::Err", 0 |) in
                    let e := M.copy (| γ0_0 |) in
                    M.alloc (| Value.StructTuple "core::result::Result::Err" [ M.read (| e |) ] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_from_str_radix :
      M.IsAssociatedFunction Self "from_str_radix" from_str_radix.
  End Impl_usize.
  
  
  (*
  Enum FpCategory
  {
    const_params := [];
    ty_params := [];
    variants :=
      [
        {
          name := "Nan";
          item := StructTuple [];
          discriminant := None;
        };
        {
          name := "Infinite";
          item := StructTuple [];
          discriminant := None;
        };
        {
          name := "Zero";
          item := StructTuple [];
          discriminant := None;
        };
        {
          name := "Subnormal";
          item := StructTuple [];
          discriminant := None;
        };
        {
          name := "Normal";
          item := StructTuple [];
          discriminant := None;
        }
      ];
  }
  *)
  
  Module Impl_core_marker_Copy_for_core_num_FpCategory.
    Definition Self : Ty.t := Ty.path "core::num::FpCategory".
    
    Axiom Implements :
      M.IsTraitInstance
        "core::marker::Copy"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [].
  End Impl_core_marker_Copy_for_core_num_FpCategory.
  
  Module Impl_core_clone_Clone_for_core_num_FpCategory.
    Definition Self : Ty.t := Ty.path "core::num::FpCategory".
    
    (* Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| M.read (| self |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_core_num_FpCategory.
  
  Module Impl_core_marker_StructuralPartialEq_for_core_num_FpCategory.
    Definition Self : Ty.t := Ty.path "core::num::FpCategory".
    
    Axiom Implements :
      M.IsTraitInstance
        "core::marker::StructuralPartialEq"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [].
  End Impl_core_marker_StructuralPartialEq_for_core_num_FpCategory.
  
  Module Impl_core_cmp_PartialEq_for_core_num_FpCategory.
    Definition Self : Ty.t := Ty.path "core::num::FpCategory".
    
    (* PartialEq *)
    Definition eq (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            let~ __self_discr :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (|
                    "core::intrinsics::discriminant_value",
                    [ Ty.path "core::num::FpCategory" ]
                  |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ __arg1_discr :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (|
                    "core::intrinsics::discriminant_value",
                    [ Ty.path "core::num::FpCategory" ]
                  |),
                  [ M.read (| other |) ]
                |)
              |) in
            M.alloc (| BinOp.eq (| M.read (| __self_discr |), M.read (| __arg1_discr |) |) |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::cmp::PartialEq"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("eq", InstanceField.Method eq) ].
  End Impl_core_cmp_PartialEq_for_core_num_FpCategory.
  
  Module Impl_core_cmp_Eq_for_core_num_FpCategory.
    Definition Self : Ty.t := Ty.path "core::num::FpCategory".
    
    (* Eq *)
    Definition assert_receiver_is_total_eq
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::cmp::Eq"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("assert_receiver_is_total_eq", InstanceField.Method assert_receiver_is_total_eq) ].
  End Impl_core_cmp_Eq_for_core_num_FpCategory.
  
  Module Impl_core_fmt_Debug_for_core_num_FpCategory.
    Definition Self : Ty.t := Ty.path "core::num::FpCategory".
    
    (* Debug *)
    Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      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::Formatter", "write_str", [] |),
            [
              M.read (| f |);
              M.read (|
                M.match_operator (|
                  self,
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ := M.is_struct_tuple (| γ, "core::num::FpCategory::Nan" |) in
                        M.alloc (| M.read (| Value.String "Nan" |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ := M.is_struct_tuple (| γ, "core::num::FpCategory::Infinite" |) in
                        M.alloc (| M.read (| Value.String "Infinite" |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ := M.is_struct_tuple (| γ, "core::num::FpCategory::Zero" |) in
                        M.alloc (| M.read (| Value.String "Zero" |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ := M.is_struct_tuple (| γ, "core::num::FpCategory::Subnormal" |) in
                        M.alloc (| M.read (| Value.String "Subnormal" |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ := M.is_struct_tuple (| γ, "core::num::FpCategory::Normal" |) in
                        M.alloc (| M.read (| Value.String "Normal" |) |)))
                  ]
                |)
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::fmt::Debug"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
  End Impl_core_fmt_Debug_for_core_num_FpCategory.
  
  Module Impl_core_str_traits_FromStr_for_isize.
    Definition Self : Ty.t := Ty.path "isize".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "isize", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_isize.
  
  Module Impl_core_str_traits_FromStr_for_i8.
    Definition Self : Ty.t := Ty.path "i8".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i8", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_i8.
  
  Module Impl_core_str_traits_FromStr_for_i16.
    Definition Self : Ty.t := Ty.path "i16".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i16", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_i16.
  
  Module Impl_core_str_traits_FromStr_for_i32.
    Definition Self : Ty.t := Ty.path "i32".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i32", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_i32.
  
  Module Impl_core_str_traits_FromStr_for_i64.
    Definition Self : Ty.t := Ty.path "i64".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i64", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_i64.
  
  Module Impl_core_str_traits_FromStr_for_i128.
    Definition Self : Ty.t := Ty.path "i128".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "i128", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_i128.
  
  Module Impl_core_str_traits_FromStr_for_usize.
    Definition Self : Ty.t := Ty.path "usize".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "usize", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_usize.
  
  Module Impl_core_str_traits_FromStr_for_u8.
    Definition Self : Ty.t := Ty.path "u8".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u8", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_u8.
  
  Module Impl_core_str_traits_FromStr_for_u16.
    Definition Self : Ty.t := Ty.path "u16".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u16", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_u16.
  
  Module Impl_core_str_traits_FromStr_for_u32.
    Definition Self : Ty.t := Ty.path "u32".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u32", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_u32.
  
  Module Impl_core_str_traits_FromStr_for_u64.
    Definition Self : Ty.t := Ty.path "u64".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u64", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_u64.
  
  Module Impl_core_str_traits_FromStr_for_u128.
    Definition Self : Ty.t := Ty.path "u128".
    
    (*             type Err = ParseIntError; *)
    Definition _Err : Ty.t := Ty.path "core::num::error::ParseIntError".
    
    (*
                fn from_str(src: &str) -> Result<Self, ParseIntError> {
                    <$t>::from_str_radix(src, 10)
                }
    *)
    Definition from_str (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ src ] =>
        ltac:(M.monadic
          (let src := M.alloc (| src |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "u128", "from_str_radix", [] |),
            [ M.read (| src |); Value.Integer IntegerKind.U32 10 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::str::traits::FromStr"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("Err", InstanceField.Ty _Err); ("from_str", InstanceField.Method from_str) ].
  End Impl_core_str_traits_FromStr_for_u128.
  
  (*
  pub const fn can_not_overflow<T>(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool {
      radix <= 16 && digits.len() <= mem::size_of::<T>() * 2 - is_signed_ty as usize
  }
  *)
  Definition can_not_overflow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [ T ], [ radix; is_signed_ty; digits ] =>
      ltac:(M.monadic
        (let radix := M.alloc (| radix |) in
        let is_signed_ty := M.alloc (| is_signed_ty |) in
        let digits := M.alloc (| digits |) in
        LogicalOp.and (|
          BinOp.le (| M.read (| radix |), Value.Integer IntegerKind.U32 16 |),
          ltac:(M.monadic
            (BinOp.le (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                  "len",
                  []
                |),
                [ M.read (| digits |) ]
              |),
              BinOp.Wrap.sub (|
                BinOp.Wrap.mul (|
                  M.call_closure (| M.get_function (| "core::mem::size_of", [ T ] |), [] |),
                  Value.Integer IntegerKind.Usize 2
                |),
                M.rust_cast (M.read (| is_signed_ty |))
              |)
            |)))
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_can_not_overflow : M.IsFunction "core::num::can_not_overflow" can_not_overflow.
  
  (*
  const fn from_str_radix_panic_ct(_radix: u32) -> ! {
      panic!("from_str_radix_int: must lie in the range `[2, 36]`");
  }
  *)
  Definition from_str_radix_panic_ct (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ _radix ] =>
      ltac:(M.monadic
        (let _radix := M.alloc (| _radix |) in
        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 "from_str_radix_int: must lie in the range `[2, 36]`"
                      |)
                    ]
                |)
              ]
            |)
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_from_str_radix_panic_ct :
    M.IsFunction "core::num::from_str_radix_panic_ct" from_str_radix_panic_ct.
  
  (*
  fn from_str_radix_panic_rt(radix: u32) -> ! {
      panic!("from_str_radix_int: must lie in the range `[2, 36]` - found {}", radix);
  }
  *)
  Definition from_str_radix_panic_rt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ radix ] =>
      ltac:(M.monadic
        (let radix := M.alloc (| radix |) in
        M.call_closure (|
          M.get_function (| "core::panicking::panic_fmt", [] |),
          [
            M.call_closure (|
              M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_v1", [] |),
              [
                M.alloc (|
                  Value.Array
                    [
                      M.read (|
                        Value.String "from_str_radix_int: must lie in the range `[2, 36]` - found "
                      |)
                    ]
                |);
                M.alloc (|
                  Value.Array
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "core::fmt::rt::Argument",
                          "new_display",
                          [ Ty.path "u32" ]
                        |),
                        [ radix ]
                      |)
                    ]
                |)
              ]
            |)
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_from_str_radix_panic_rt :
    M.IsFunction "core::num::from_str_radix_panic_rt" from_str_radix_panic_rt.
  
  (*
  const fn from_str_radix_panic(radix: u32) {
      // The only difference between these two functions is their panic message.
      intrinsics::const_eval_select((radix,), from_str_radix_panic_ct, from_str_radix_panic_rt);
  }
  *)
  Definition from_str_radix_panic (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ radix ] =>
      ltac:(M.monadic
        (let radix := M.alloc (| radix |) in
        M.never_to_any (|
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::const_eval_select",
              [
                Ty.tuple [ Ty.path "u32" ];
                Ty.function [ Ty.path "u32" ] (Ty.path "never");
                Ty.function [ Ty.path "u32" ] (Ty.path "never");
                Ty.path "never"
              ]
            |),
            [
              Value.Tuple [ M.read (| radix |) ];
              M.get_function (| "core::num::from_str_radix_panic_ct", [] |);
              M.get_function (| "core::num::from_str_radix_panic_rt", [] |)
            ]
          |)
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_from_str_radix_panic :
    M.IsFunction "core::num::from_str_radix_panic" from_str_radix_panic.
  
  
  
  
  
  
  
  
  
  
  
  
End num.
