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

Module iter.
  Module adapters.
    Module take.
      (* StructRecord
        {
          name := "Take";
          const_params := [];
          ty_params := [ "I" ];
          fields := [ ("iter", I); ("n", Ty.path "usize") ];
        } *)
      
      Module Impl_core_clone_Clone_where_core_clone_Clone_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        (* Clone *)
        Definition clone (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              Value.StructRecord
                "core::iter::adapters::take::Take"
                [
                  ("iter",
                    M.call_closure (|
                      M.get_trait_method (| "core::clone::Clone", I, [], "clone", [] |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::iter::adapters::take::Take",
                          "iter"
                        |)
                      ]
                    |));
                  ("n",
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::clone::Clone",
                        Ty.path "usize",
                        [],
                        "clone",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::iter::adapters::take::Take",
                          "n"
                        |)
                      ]
                    |))
                ]))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::clone::Clone"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("clone", InstanceField.Method (clone I)) ].
      End Impl_core_clone_Clone_where_core_clone_Clone_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_fmt_Debug_where_core_fmt_Debug_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        (* Debug *)
        Definition fmt (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [], [ self; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let f := M.alloc (| f |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "core::fmt::Formatter",
                  "debug_struct_field2_finish",
                  []
                |),
                [
                  M.read (| f |);
                  M.read (| Value.String "Take" |);
                  M.read (| Value.String "iter" |);
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::iter::adapters::take::Take",
                    "iter"
                  |);
                  M.read (| Value.String "n" |);
                  M.alloc (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "core::iter::adapters::take::Take",
                      "n"
                    |)
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::fmt::Debug"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("fmt", InstanceField.Method (fmt I)) ].
      End Impl_core_fmt_Debug_where_core_fmt_Debug_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        (*
            pub(in crate::iter) fn new(iter: I, n: usize) -> Take<I> {
                Take { iter, n }
            }
        *)
        Definition new (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [], [ iter; n ] =>
            ltac:(M.monadic
              (let iter := M.alloc (| iter |) in
              let n := M.alloc (| n |) in
              Value.StructRecord
                "core::iter::adapters::take::Take"
                [ ("iter", M.read (| iter |)); ("n", M.read (| n |)) ]))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_new :
          forall (I : Ty.t),
          M.IsAssociatedFunction (Self I) "new" (new I).
      End Impl_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_traits_iterator_Iterator_where_core_iter_traits_iterator_Iterator_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        (*     type Item = <I as Iterator>::Item; *)
        Definition _Item (I : Ty.t) : Ty.t := Ty.associated.
        
        (*
            fn next(&mut self) -> Option<<I as Iterator>::Item> {
                if self.n != 0 {
                    self.n -= 1;
                    self.iter.next()
                } else {
                    None
                }
            }
        *)
        Definition next (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.read (|
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.ne (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::take::Take",
                                    "n"
                                  |)
                                |),
                                Value.Integer IntegerKind.Usize 0
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        let~ _ :=
                          let β :=
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::take::Take",
                              "n"
                            |) in
                          M.write (|
                            β,
                            BinOp.Wrap.sub (| M.read (| β |), Value.Integer IntegerKind.Usize 1 |)
                          |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              I,
                              [],
                              "next",
                              []
                            |),
                            [
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "core::iter::adapters::take::Take",
                                "iter"
                              |)
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn nth(&mut self, n: usize) -> Option<I::Item> {
                if self.n > n {
                    self.n -= n + 1;
                    self.iter.nth(n)
                } else {
                    if self.n > 0 {
                        self.iter.nth(self.n - 1);
                        self.n = 0;
                    }
                    None
                }
            }
        *)
        Definition nth (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [], [ self; n ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let n := M.alloc (| n |) in
              M.read (|
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.gt (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::take::Take",
                                    "n"
                                  |)
                                |),
                                M.read (| n |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        let~ _ :=
                          let β :=
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::take::Take",
                              "n"
                            |) in
                          M.write (|
                            β,
                            BinOp.Wrap.sub (|
                              M.read (| β |),
                              BinOp.Wrap.add (| M.read (| n |), Value.Integer IntegerKind.Usize 1 |)
                            |)
                          |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              I,
                              [],
                              "nth",
                              []
                            |),
                            [
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "core::iter::adapters::take::Take",
                                "iter"
                              |);
                              M.read (| n |)
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let~ _ :=
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ :=
                                    M.use
                                      (M.alloc (|
                                        BinOp.gt (|
                                          M.read (|
                                            M.SubPointer.get_struct_record_field (|
                                              M.read (| self |),
                                              "core::iter::adapters::take::Take",
                                              "n"
                                            |)
                                          |),
                                          Value.Integer IntegerKind.Usize 0
                                        |)
                                      |)) in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  let~ _ :=
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::iter::traits::iterator::Iterator",
                                          I,
                                          [],
                                          "nth",
                                          []
                                        |),
                                        [
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "core::iter::adapters::take::Take",
                                            "iter"
                                          |);
                                          BinOp.Wrap.sub (|
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::iter::adapters::take::Take",
                                                "n"
                                              |)
                                            |),
                                            Value.Integer IntegerKind.Usize 1
                                          |)
                                        ]
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::iter::adapters::take::Take",
                                        "n"
                                      |),
                                      Value.Integer IntegerKind.Usize 0
                                    |) in
                                  M.alloc (| Value.Tuple [] |)));
                              fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn size_hint(&self) -> (usize, Option<usize>) {
                if self.n == 0 {
                    return (0, Some(0));
                }
        
                let (lower, upper) = self.iter.size_hint();
        
                let lower = cmp::min(lower, self.n);
        
                let upper = match upper {
                    Some(x) if x < self.n => Some(x),
                    _ => Some(self.n),
                };
        
                (lower, upper)
            }
        *)
        Definition size_hint (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          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.eq (|
                                      M.read (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::iter::adapters::take::Take",
                                          "n"
                                        |)
                                      |),
                                      Value.Integer IntegerKind.Usize 0
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    M.return_ (|
                                      Value.Tuple
                                        [
                                          Value.Integer IntegerKind.Usize 0;
                                          Value.StructTuple
                                            "core::option::Option::Some"
                                            [ Value.Integer IntegerKind.Usize 0 ]
                                        ]
                                    |)
                                  |)
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::iter::traits::iterator::Iterator",
                            I,
                            [],
                            "size_hint",
                            []
                          |),
                          [
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::take::Take",
                              "iter"
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                            let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                            let lower := M.copy (| γ0_0 |) in
                            let upper := M.copy (| γ0_1 |) in
                            let~ lower :=
                              M.alloc (|
                                M.call_closure (|
                                  M.get_function (| "core::cmp::min", [ Ty.path "usize" ] |),
                                  [
                                    M.read (| lower |);
                                    M.read (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::iter::adapters::take::Take",
                                        "n"
                                      |)
                                    |)
                                  ]
                                |)
                              |) in
                            let~ upper :=
                              M.copy (|
                                M.match_operator (|
                                  upper,
                                  [
                                    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
                                        let γ :=
                                          M.alloc (|
                                            BinOp.lt (|
                                              M.read (| x |),
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::iter::adapters::take::Take",
                                                  "n"
                                                |)
                                              |)
                                            |)
                                          |) in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        M.alloc (|
                                          Value.StructTuple
                                            "core::option::Option::Some"
                                            [ M.read (| x |) ]
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (M.alloc (|
                                          Value.StructTuple
                                            "core::option::Option::Some"
                                            [
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::iter::adapters::take::Take",
                                                  "n"
                                                |)
                                              |)
                                            ]
                                        |)))
                                  ]
                                |)
                              |) in
                            M.alloc (| Value.Tuple [ M.read (| lower |); M.read (| upper |) ] |)))
                      ]
                    |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
            where
                Fold: FnMut(Acc, Self::Item) -> R,
                R: Try<Output = Acc>,
            {
                fn check<'a, T, Acc, R: Try<Output = Acc>>(
                    n: &'a mut usize,
                    mut fold: impl FnMut(Acc, T) -> R + 'a,
                ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
                    move |acc, x| {
                        *n -= 1;
                        let r = fold(acc, x);
                        if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
                    }
                }
        
                if self.n == 0 {
                    try { init }
                } else {
                    let n = &mut self.n;
                    self.iter.try_fold(init, check(n, fold)).into_try()
                }
            }
        *)
        Definition try_fold (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [ Acc; Fold; R ], [ self; init; fold ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let fold := M.alloc (| fold |) in
              M.read (|
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::take::Take",
                                    "n"
                                  |)
                                |),
                                Value.Integer IntegerKind.Usize 0
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::ops::try_trait::Try",
                              R,
                              [],
                              "from_output",
                              []
                            |),
                            [ M.read (| init |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let~ n :=
                          M.alloc (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::take::Take",
                              "n"
                            |)
                          |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "core::ops::control_flow::ControlFlow")
                                []
                                [ R; Ty.associated ],
                              "into_try",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::iterator::Iterator",
                                  I,
                                  [],
                                  "try_fold",
                                  [
                                    Acc;
                                    Ty.associated;
                                    Ty.apply
                                      (Ty.path "core::ops::control_flow::ControlFlow")
                                      []
                                      [ R; Acc ]
                                  ]
                                |),
                                [
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::take::Take",
                                    "iter"
                                  |);
                                  M.read (| init |);
                                  M.call_closure (|
                                    M.get_associated_function (| Self, "check.try_fold", [] |),
                                    [ M.read (| n |); M.read (| fold |) ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn fold<B, F>(self, init: B, f: F) -> B
            where
                Self: Sized,
                F: FnMut(B, Self::Item) -> B,
            {
                Self::spec_fold(self, init, f)
            }
        *)
        Definition fold (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [ B; F ], [ self; init; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let f := M.alloc (| f |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::adapters::take::SpecTake",
                  Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ],
                  [],
                  "spec_fold",
                  [ B; F ]
                |),
                [ M.read (| self |); M.read (| init |); M.read (| f |) ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn for_each<F: FnMut(Self::Item)>(self, f: F) {
                Self::spec_for_each(self, f)
            }
        *)
        Definition for_each (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [ F ], [ self; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let f := M.alloc (| f |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::adapters::take::SpecTake",
                  Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ],
                  [],
                  "spec_for_each",
                  [ F ]
                |),
                [ M.read (| self |); M.read (| f |) ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
                let min = self.n.min(n);
                let rem = match self.iter.advance_by(min) {
                    Ok(()) => 0,
                    Err(rem) => rem.get(),
                };
                let advanced = min - rem;
                self.n -= advanced;
                NonZero::new(n - advanced).map_or(Ok(()), Err)
            }
        *)
        Definition advance_by
            (I : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [], [ self; n ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let n := M.alloc (| n |) in
              M.read (|
                let~ min :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (| "core::cmp::Ord", Ty.path "usize", [], "min", [] |),
                      [
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "core::iter::adapters::take::Take",
                            "n"
                          |)
                        |);
                        M.read (| n |)
                      ]
                    |)
                  |) in
                let~ rem :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::iter::traits::iterator::Iterator",
                            I,
                            [],
                            "advance_by",
                            []
                          |),
                          [
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::take::Take",
                              "iter"
                            |);
                            M.read (| min |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::result::Result::Ok",
                                0
                              |) in
                            M.alloc (| Value.Integer IntegerKind.Usize 0 |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::result::Result::Err",
                                0
                              |) in
                            let rem := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "core::num::nonzero::NonZero")
                                    []
                                    [ Ty.path "usize" ],
                                  "get",
                                  []
                                |),
                                [ M.read (| rem |) ]
                              |)
                            |)))
                      ]
                    |)
                  |) in
                let~ advanced :=
                  M.alloc (| BinOp.Wrap.sub (| M.read (| min |), M.read (| rem |) |) |) in
                let~ _ :=
                  let β :=
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "core::iter::adapters::take::Take",
                      "n"
                    |) in
                  M.write (| β, BinOp.Wrap.sub (| M.read (| β |), M.read (| advanced |) |) |) in
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "core::option::Option")
                        []
                        [ Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ] ],
                      "map_or",
                      [
                        Ty.apply
                          (Ty.path "core::result::Result")
                          []
                          [
                            Ty.tuple [];
                            Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ]
                          ];
                        Ty.function
                          [ Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ]
                          ]
                          (Ty.apply
                            (Ty.path "core::result::Result")
                            []
                            [
                              Ty.tuple [];
                              Ty.apply
                                (Ty.path "core::num::nonzero::NonZero")
                                []
                                [ Ty.path "usize" ]
                            ])
                      ]
                    |),
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ],
                          "new",
                          []
                        |),
                        [ BinOp.Wrap.sub (| M.read (| n |), M.read (| advanced |) |) ]
                      |);
                      Value.StructTuple "core::result::Result::Ok" [ Value.Tuple [] ];
                      M.constructor_as_closure "core::result::Result::Err"
                    ]
                  |)
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::iterator::Iterator"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("Item", InstanceField.Ty (_Item I));
              ("next", InstanceField.Method (next I));
              ("nth", InstanceField.Method (nth I));
              ("size_hint", InstanceField.Method (size_hint I));
              ("try_fold", InstanceField.Method (try_fold I));
              ("fold", InstanceField.Method (fold I));
              ("for_each", InstanceField.Method (for_each I));
              ("advance_by", InstanceField.Method (advance_by I))
            ].
      End Impl_core_iter_traits_iterator_Iterator_where_core_iter_traits_iterator_Iterator_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_adapters_SourceIter_where_core_iter_adapters_SourceIter_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        (*     type Source = I::Source; *)
        Definition _Source (I : Ty.t) : Ty.t := Ty.associated.
        
        (*
            unsafe fn as_inner(&mut self) -> &mut I::Source {
                // SAFETY: unsafe function forwarding to unsafe function with the same requirements
                unsafe { SourceIter::as_inner(&mut self.iter) }
            }
        *)
        Definition as_inner (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.call_closure (|
                M.get_trait_method (| "core::iter::adapters::SourceIter", I, [], "as_inner", [] |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::iter::adapters::take::Take",
                    "iter"
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::iter::adapters::SourceIter"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("Source", InstanceField.Ty (_Source I));
              ("as_inner", InstanceField.Method (as_inner I))
            ].
      End Impl_core_iter_adapters_SourceIter_where_core_iter_adapters_SourceIter_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_traits_marker_InPlaceIterable_where_core_iter_traits_marker_InPlaceIterable_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        (*     const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY; *)
        (* Ty.apply
          (Ty.path "core::option::Option")
          []
          [ Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ] ] *)
        Definition value_EXPAND_BY (I : Ty.t) : Value.t :=
          let Self : Ty.t := Self I in
          M.run
            ltac:(M.monadic
              (M.get_constant (| "core::iter::traits::marker::InPlaceIterable::EXPAND_BY" |))).
        
        (*     const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY; *)
        (* Ty.apply
          (Ty.path "core::option::Option")
          []
          [ Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ] ] *)
        Definition value_MERGE_BY (I : Ty.t) : Value.t :=
          let Self : Ty.t := Self I in
          M.run
            ltac:(M.monadic
              (M.get_constant (| "core::iter::traits::marker::InPlaceIterable::MERGE_BY" |))).
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::marker::InPlaceIterable"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("value_EXPAND_BY", InstanceField.Constant (value_EXPAND_BY I));
              ("value_MERGE_BY", InstanceField.Constant (value_MERGE_BY I))
            ].
      End Impl_core_iter_traits_marker_InPlaceIterable_where_core_iter_traits_marker_InPlaceIterable_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_traits_double_ended_DoubleEndedIterator_where_core_iter_traits_double_ended_DoubleEndedIterator_I_where_core_iter_traits_exact_size_ExactSizeIterator_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        (*
            fn next_back(&mut self) -> Option<Self::Item> {
                if self.n == 0 {
                    None
                } else {
                    let n = self.n;
                    self.n -= 1;
                    self.iter.nth_back(self.iter.len().saturating_sub(n))
                }
            }
        *)
        Definition next_back (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.read (|
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::take::Take",
                                    "n"
                                  |)
                                |),
                                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
                        (let~ n :=
                          M.copy (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::take::Take",
                              "n"
                            |)
                          |) in
                        let~ _ :=
                          let β :=
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::take::Take",
                              "n"
                            |) in
                          M.write (|
                            β,
                            BinOp.Wrap.sub (| M.read (| β |), Value.Integer IntegerKind.Usize 1 |)
                          |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::double_ended::DoubleEndedIterator",
                              I,
                              [],
                              "nth_back",
                              []
                            |),
                            [
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "core::iter::adapters::take::Take",
                                "iter"
                              |);
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "usize",
                                  "saturating_sub",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::iter::traits::exact_size::ExactSizeIterator",
                                      I,
                                      [],
                                      "len",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::iter::adapters::take::Take",
                                        "iter"
                                      |)
                                    ]
                                  |);
                                  M.read (| n |)
                                ]
                              |)
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
                let len = self.iter.len();
                if self.n > n {
                    let m = len.saturating_sub(self.n) + n;
                    self.n -= n + 1;
                    self.iter.nth_back(m)
                } else {
                    if len > 0 {
                        self.iter.nth_back(len - 1);
                    }
                    None
                }
            }
        *)
        Definition nth_back (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [], [ self; n ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let n := M.alloc (| n |) in
              M.read (|
                let~ len :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::iter::traits::exact_size::ExactSizeIterator",
                        I,
                        [],
                        "len",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::iter::adapters::take::Take",
                          "iter"
                        |)
                      ]
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.gt (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::take::Take",
                                    "n"
                                  |)
                                |),
                                M.read (| n |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        let~ m :=
                          M.alloc (|
                            BinOp.Wrap.add (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "usize",
                                  "saturating_sub",
                                  []
                                |),
                                [
                                  M.read (| len |);
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "core::iter::adapters::take::Take",
                                      "n"
                                    |)
                                  |)
                                ]
                              |),
                              M.read (| n |)
                            |)
                          |) in
                        let~ _ :=
                          let β :=
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::take::Take",
                              "n"
                            |) in
                          M.write (|
                            β,
                            BinOp.Wrap.sub (|
                              M.read (| β |),
                              BinOp.Wrap.add (| M.read (| n |), Value.Integer IntegerKind.Usize 1 |)
                            |)
                          |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::double_ended::DoubleEndedIterator",
                              I,
                              [],
                              "nth_back",
                              []
                            |),
                            [
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "core::iter::adapters::take::Take",
                                "iter"
                              |);
                              M.read (| m |)
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let~ _ :=
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ :=
                                    M.use
                                      (M.alloc (|
                                        BinOp.gt (|
                                          M.read (| len |),
                                          Value.Integer IntegerKind.Usize 0
                                        |)
                                      |)) in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  let~ _ :=
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::iter::traits::double_ended::DoubleEndedIterator",
                                          I,
                                          [],
                                          "nth_back",
                                          []
                                        |),
                                        [
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "core::iter::adapters::take::Take",
                                            "iter"
                                          |);
                                          BinOp.Wrap.sub (|
                                            M.read (| len |),
                                            Value.Integer IntegerKind.Usize 1
                                          |)
                                        ]
                                      |)
                                    |) in
                                  M.alloc (| Value.Tuple [] |)));
                              fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
            where
                Self: Sized,
                Fold: FnMut(Acc, Self::Item) -> R,
                R: Try<Output = Acc>,
            {
                if self.n == 0 {
                    try { init }
                } else {
                    let len = self.iter.len();
                    if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
                        try { init }
                    } else {
                        self.iter.try_rfold(init, fold)
                    }
                }
            }
        *)
        Definition try_rfold (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [ Acc; Fold; R ], [ self; init; fold ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let fold := M.alloc (| fold |) in
              M.read (|
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::take::Take",
                                    "n"
                                  |)
                                |),
                                Value.Integer IntegerKind.Usize 0
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::ops::try_trait::Try",
                              R,
                              [],
                              "from_output",
                              []
                            |),
                            [ M.read (| init |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let~ len :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::exact_size::ExactSizeIterator",
                                I,
                                [],
                                "len",
                                []
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::take::Take",
                                  "iter"
                                |)
                              ]
                            |)
                          |) in
                        M.match_operator (|
                          M.alloc (| Value.Tuple [] |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ :=
                                  M.use
                                    (M.alloc (|
                                      LogicalOp.and (|
                                        BinOp.gt (|
                                          M.read (| len |),
                                          M.read (|
                                            M.SubPointer.get_struct_record_field (|
                                              M.read (| self |),
                                              "core::iter::adapters::take::Take",
                                              "n"
                                            |)
                                          |)
                                        |),
                                        ltac:(M.monadic
                                          (M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply
                                                (Ty.path "core::option::Option")
                                                []
                                                [ Ty.associated ],
                                              "is_none",
                                              []
                                            |),
                                            [
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::iter::traits::double_ended::DoubleEndedIterator",
                                                    I,
                                                    [],
                                                    "nth_back",
                                                    []
                                                  |),
                                                  [
                                                    M.SubPointer.get_struct_record_field (|
                                                      M.read (| self |),
                                                      "core::iter::adapters::take::Take",
                                                      "iter"
                                                    |);
                                                    BinOp.Wrap.sub (|
                                                      BinOp.Wrap.sub (|
                                                        M.read (| len |),
                                                        M.read (|
                                                          M.SubPointer.get_struct_record_field (|
                                                            M.read (| self |),
                                                            "core::iter::adapters::take::Take",
                                                            "n"
                                                          |)
                                                        |)
                                                      |),
                                                      Value.Integer IntegerKind.Usize 1
                                                    |)
                                                  ]
                                                |)
                                              |)
                                            ]
                                          |)))
                                      |)
                                    |)) in
                                let _ :=
                                  M.is_constant_or_break_match (|
                                    M.read (| γ |),
                                    Value.Bool true
                                  |) in
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::try_trait::Try",
                                      R,
                                      [],
                                      "from_output",
                                      []
                                    |),
                                    [ M.read (| init |) ]
                                  |)
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (M.alloc (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::iter::traits::double_ended::DoubleEndedIterator",
                                      I,
                                      [],
                                      "try_rfold",
                                      [ Acc; Fold; R ]
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::iter::adapters::take::Take",
                                        "iter"
                                      |);
                                      M.read (| init |);
                                      M.read (| fold |)
                                    ]
                                  |)
                                |)))
                          ]
                        |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
            where
                Self: Sized,
                Fold: FnMut(Acc, Self::Item) -> Acc,
            {
                if self.n == 0 {
                    init
                } else {
                    let len = self.iter.len();
                    if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
                        init
                    } else {
                        self.iter.rfold(init, fold)
                    }
                }
            }
        *)
        Definition rfold (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [ Acc; Fold ], [ self; init; fold ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let fold := M.alloc (| fold |) in
              M.read (|
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.eq (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    self,
                                    "core::iter::adapters::take::Take",
                                    "n"
                                  |)
                                |),
                                Value.Integer IntegerKind.Usize 0
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        init));
                    fun γ =>
                      ltac:(M.monadic
                        (let~ len :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::exact_size::ExactSizeIterator",
                                I,
                                [],
                                "len",
                                []
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  self,
                                  "core::iter::adapters::take::Take",
                                  "iter"
                                |)
                              ]
                            |)
                          |) in
                        M.match_operator (|
                          M.alloc (| Value.Tuple [] |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ :=
                                  M.use
                                    (M.alloc (|
                                      LogicalOp.and (|
                                        BinOp.gt (|
                                          M.read (| len |),
                                          M.read (|
                                            M.SubPointer.get_struct_record_field (|
                                              self,
                                              "core::iter::adapters::take::Take",
                                              "n"
                                            |)
                                          |)
                                        |),
                                        ltac:(M.monadic
                                          (M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply
                                                (Ty.path "core::option::Option")
                                                []
                                                [ Ty.associated ],
                                              "is_none",
                                              []
                                            |),
                                            [
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::iter::traits::double_ended::DoubleEndedIterator",
                                                    I,
                                                    [],
                                                    "nth_back",
                                                    []
                                                  |),
                                                  [
                                                    M.SubPointer.get_struct_record_field (|
                                                      self,
                                                      "core::iter::adapters::take::Take",
                                                      "iter"
                                                    |);
                                                    BinOp.Wrap.sub (|
                                                      BinOp.Wrap.sub (|
                                                        M.read (| len |),
                                                        M.read (|
                                                          M.SubPointer.get_struct_record_field (|
                                                            self,
                                                            "core::iter::adapters::take::Take",
                                                            "n"
                                                          |)
                                                        |)
                                                      |),
                                                      Value.Integer IntegerKind.Usize 1
                                                    |)
                                                  ]
                                                |)
                                              |)
                                            ]
                                          |)))
                                      |)
                                    |)) in
                                let _ :=
                                  M.is_constant_or_break_match (|
                                    M.read (| γ |),
                                    Value.Bool true
                                  |) in
                                init));
                            fun γ =>
                              ltac:(M.monadic
                                (M.alloc (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::iter::traits::double_ended::DoubleEndedIterator",
                                      I,
                                      [],
                                      "rfold",
                                      [ Acc; Fold ]
                                    |),
                                    [
                                      M.read (|
                                        M.SubPointer.get_struct_record_field (|
                                          self,
                                          "core::iter::adapters::take::Take",
                                          "iter"
                                        |)
                                      |);
                                      M.read (| init |);
                                      M.read (| fold |)
                                    ]
                                  |)
                                |)))
                          ]
                        |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
                // The amount by which the inner iterator needs to be shortened for it to be
                // at most as long as the take() amount.
                let trim_inner = self.iter.len().saturating_sub(self.n);
                // The amount we need to advance inner to fulfill the caller's request.
                // take(), advance_by() and len() all can be at most usize, so we don't have to worry
                // about having to advance more than usize::MAX here.
                let advance_by = trim_inner.saturating_add(n);
        
                let remainder = match self.iter.advance_back_by(advance_by) {
                    Ok(()) => 0,
                    Err(rem) => rem.get(),
                };
                let advanced_by_inner = advance_by - remainder;
                let advanced_by = advanced_by_inner - trim_inner;
                self.n -= advanced_by;
                NonZero::new(n - advanced_by).map_or(Ok(()), Err)
            }
        *)
        Definition advance_back_by
            (I : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [], [ self; n ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let n := M.alloc (| n |) in
              M.read (|
                let~ trim_inner :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "usize", "saturating_sub", [] |),
                      [
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::iter::traits::exact_size::ExactSizeIterator",
                            I,
                            [],
                            "len",
                            []
                          |),
                          [
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::take::Take",
                              "iter"
                            |)
                          ]
                        |);
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "core::iter::adapters::take::Take",
                            "n"
                          |)
                        |)
                      ]
                    |)
                  |) in
                let~ advance_by :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "usize", "saturating_add", [] |),
                      [ M.read (| trim_inner |); M.read (| n |) ]
                    |)
                  |) in
                let~ remainder :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::iter::traits::double_ended::DoubleEndedIterator",
                            I,
                            [],
                            "advance_back_by",
                            []
                          |),
                          [
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::take::Take",
                              "iter"
                            |);
                            M.read (| advance_by |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::result::Result::Ok",
                                0
                              |) in
                            M.alloc (| Value.Integer IntegerKind.Usize 0 |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::result::Result::Err",
                                0
                              |) in
                            let rem := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "core::num::nonzero::NonZero")
                                    []
                                    [ Ty.path "usize" ],
                                  "get",
                                  []
                                |),
                                [ M.read (| rem |) ]
                              |)
                            |)))
                      ]
                    |)
                  |) in
                let~ advanced_by_inner :=
                  M.alloc (|
                    BinOp.Wrap.sub (| M.read (| advance_by |), M.read (| remainder |) |)
                  |) in
                let~ advanced_by :=
                  M.alloc (|
                    BinOp.Wrap.sub (| M.read (| advanced_by_inner |), M.read (| trim_inner |) |)
                  |) in
                let~ _ :=
                  let β :=
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "core::iter::adapters::take::Take",
                      "n"
                    |) in
                  M.write (| β, BinOp.Wrap.sub (| M.read (| β |), M.read (| advanced_by |) |) |) in
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "core::option::Option")
                        []
                        [ Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ] ],
                      "map_or",
                      [
                        Ty.apply
                          (Ty.path "core::result::Result")
                          []
                          [
                            Ty.tuple [];
                            Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ]
                          ];
                        Ty.function
                          [ Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ]
                          ]
                          (Ty.apply
                            (Ty.path "core::result::Result")
                            []
                            [
                              Ty.tuple [];
                              Ty.apply
                                (Ty.path "core::num::nonzero::NonZero")
                                []
                                [ Ty.path "usize" ]
                            ])
                      ]
                    |),
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ],
                          "new",
                          []
                        |),
                        [ BinOp.Wrap.sub (| M.read (| n |), M.read (| advanced_by |) |) ]
                      |);
                      Value.StructTuple "core::result::Result::Ok" [ Value.Tuple [] ];
                      M.constructor_as_closure "core::result::Result::Err"
                    ]
                  |)
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::double_ended::DoubleEndedIterator"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("next_back", InstanceField.Method (next_back I));
              ("nth_back", InstanceField.Method (nth_back I));
              ("try_rfold", InstanceField.Method (try_rfold I));
              ("rfold", InstanceField.Method (rfold I));
              ("advance_back_by", InstanceField.Method (advance_back_by I))
            ].
      End Impl_core_iter_traits_double_ended_DoubleEndedIterator_where_core_iter_traits_double_ended_DoubleEndedIterator_I_where_core_iter_traits_exact_size_ExactSizeIterator_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_traits_exact_size_ExactSizeIterator_where_core_iter_traits_exact_size_ExactSizeIterator_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::exact_size::ExactSizeIterator"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *) [].
      End Impl_core_iter_traits_exact_size_ExactSizeIterator_where_core_iter_traits_exact_size_ExactSizeIterator_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_traits_marker_FusedIterator_where_core_iter_traits_marker_FusedIterator_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::marker::FusedIterator"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *) [].
      End Impl_core_iter_traits_marker_FusedIterator_where_core_iter_traits_marker_FusedIterator_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_traits_marker_TrustedFused_where_core_iter_traits_marker_TrustedFused_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::marker::TrustedFused"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *) [].
      End Impl_core_iter_traits_marker_TrustedFused_where_core_iter_traits_marker_TrustedFused_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_traits_marker_TrustedLen_where_core_iter_traits_marker_TrustedLen_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::marker::TrustedLen"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *) [].
      End Impl_core_iter_traits_marker_TrustedLen_where_core_iter_traits_marker_TrustedLen_I_for_core_iter_adapters_take_Take_I.
      
      (* Trait *)
      (* Empty module 'SpecTake' *)
      
      Module Impl_core_iter_adapters_take_SpecTake_where_core_iter_traits_iterator_Iterator_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        (*
            default fn spec_fold<B, F>(mut self, init: B, f: F) -> B
            where
                Self: Sized,
                F: FnMut(B, Self::Item) -> B,
            {
                use crate::ops::NeverShortCircuit;
                self.try_fold(init, NeverShortCircuit::wrap_mut_2(f)).0
            }
        *)
        Definition spec_fold (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [ B; F ], [ self; init; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let f := M.alloc (| f |) in
              M.read (|
                M.SubPointer.get_struct_tuple_field (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::iter::traits::iterator::Iterator",
                        Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ],
                        [],
                        "try_fold",
                        [
                          B;
                          Ty.associated;
                          Ty.apply (Ty.path "core::ops::try_trait::NeverShortCircuit") [] [ B ]
                        ]
                      |),
                      [
                        self;
                        M.read (| init |);
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "core::ops::try_trait::NeverShortCircuit") [] [ B ],
                            "wrap_mut_2",
                            [ B; Ty.associated; F ]
                          |),
                          [ M.read (| f |) ]
                        |)
                      ]
                    |)
                  |),
                  "core::ops::try_trait::NeverShortCircuit",
                  0
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            default fn spec_for_each<F: FnMut(Self::Item)>(mut self, f: F) {
                // The default implementation would use a unit accumulator, so we can
                // avoid a stateful closure by folding over the remaining number
                // of items we wish to return instead.
                fn check<'a, Item>(
                    mut action: impl FnMut(Item) + 'a,
                ) -> impl FnMut(usize, Item) -> Option<usize> + 'a {
                    move |more, x| {
                        action(x);
                        more.checked_sub(1)
                    }
                }
        
                let remaining = self.n;
                if remaining > 0 {
                    self.iter.try_fold(remaining - 1, check(f));
                }
            }
        *)
        Definition spec_for_each
            (I : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [ F ], [ self; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let f := M.alloc (| f |) in
              M.read (|
                let~ remaining :=
                  M.copy (|
                    M.SubPointer.get_struct_record_field (|
                      self,
                      "core::iter::adapters::take::Take",
                      "n"
                    |)
                  |) in
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              BinOp.gt (|
                                M.read (| remaining |),
                                Value.Integer IntegerKind.Usize 0
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        let~ _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::iterator::Iterator",
                                I,
                                [],
                                "try_fold",
                                [
                                  Ty.path "usize";
                                  Ty.associated;
                                  Ty.apply (Ty.path "core::option::Option") [] [ Ty.path "usize" ]
                                ]
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  self,
                                  "core::iter::adapters::take::Take",
                                  "iter"
                                |);
                                BinOp.Wrap.sub (|
                                  M.read (| remaining |),
                                  Value.Integer IntegerKind.Usize 1
                                |);
                                M.call_closure (|
                                  M.get_associated_function (| Self, "check.spec_for_each", [] |),
                                  [ M.read (| f |) ]
                                |)
                              ]
                            |)
                          |) in
                        M.alloc (| Value.Tuple [] |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::iter::adapters::take::SpecTake"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("spec_fold", InstanceField.Method (spec_fold I));
              ("spec_for_each", InstanceField.Method (spec_for_each I))
            ].
      End Impl_core_iter_adapters_take_SpecTake_where_core_iter_traits_iterator_Iterator_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_adapters_take_SpecTake_where_core_iter_traits_iterator_Iterator_I_where_core_iter_adapters_zip_TrustedRandomAccess_I_for_core_iter_adapters_take_Take_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::take::Take") [] [ I ].
        
        (*
            fn spec_fold<B, F>(mut self, init: B, mut f: F) -> B
            where
                Self: Sized,
                F: FnMut(B, Self::Item) -> B,
            {
                let mut acc = init;
                let end = self.n.min(self.iter.size());
                for i in 0..end {
                    // SAFETY: i < end <= self.iter.size() and we discard the iterator at the end
                    let val = unsafe { self.iter.__iterator_get_unchecked(i) };
                    acc = f(acc, val);
                }
                acc
            }
        *)
        Definition spec_fold (I : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [ B; F ], [ self; init; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let f := M.alloc (| f |) in
              M.read (|
                let~ acc := M.copy (| init |) in
                let~ end_ :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (| "core::cmp::Ord", Ty.path "usize", [], "min", [] |),
                      [
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            self,
                            "core::iter::adapters::take::Take",
                            "n"
                          |)
                        |);
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::iter::adapters::zip::TrustedRandomAccessNoCoerce",
                            I,
                            [],
                            "size",
                            []
                          |),
                          [
                            M.SubPointer.get_struct_record_field (|
                              self,
                              "core::iter::adapters::take::Take",
                              "iter"
                            |)
                          ]
                        |)
                      ]
                    |)
                  |) in
                let~ _ :=
                  M.use
                    (M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::iter::traits::collect::IntoIterator",
                            Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ],
                            [],
                            "into_iter",
                            []
                          |),
                          [
                            Value.StructRecord
                              "core::ops::range::Range"
                              [
                                ("start", Value.Integer IntegerKind.Usize 0);
                                ("end_", M.read (| end_ |))
                              ]
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let iter := M.copy (| γ |) in
                            M.loop (|
                              ltac:(M.monadic
                                (let~ _ :=
                                  M.match_operator (|
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::iter::traits::iterator::Iterator",
                                          Ty.apply
                                            (Ty.path "core::ops::range::Range")
                                            []
                                            [ Ty.path "usize" ],
                                          [],
                                          "next",
                                          []
                                        |),
                                        [ iter ]
                                      |)
                                    |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let _ :=
                                            M.is_struct_tuple (|
                                              γ,
                                              "core::option::Option::None"
                                            |) in
                                          M.alloc (|
                                            M.never_to_any (| M.read (| M.break (||) |) |)
                                          |)));
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ0_0 :=
                                            M.SubPointer.get_struct_tuple_field (|
                                              γ,
                                              "core::option::Option::Some",
                                              0
                                            |) in
                                          let i := M.copy (| γ0_0 |) in
                                          let~ val :=
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::iter::traits::iterator::Iterator",
                                                  I,
                                                  [],
                                                  "__iterator_get_unchecked",
                                                  []
                                                |),
                                                [
                                                  M.SubPointer.get_struct_record_field (|
                                                    self,
                                                    "core::iter::adapters::take::Take",
                                                    "iter"
                                                  |);
                                                  M.read (| i |)
                                                ]
                                              |)
                                            |) in
                                          let~ _ :=
                                            M.write (|
                                              acc,
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::function::FnMut",
                                                  F,
                                                  [ Ty.tuple [ B; Ty.associated ] ],
                                                  "call_mut",
                                                  []
                                                |),
                                                [
                                                  f;
                                                  Value.Tuple [ M.read (| acc |); M.read (| val |) ]
                                                ]
                                              |)
                                            |) in
                                          M.alloc (| Value.Tuple [] |)))
                                    ]
                                  |) in
                                M.alloc (| Value.Tuple [] |)))
                            |)))
                      ]
                    |)) in
                acc
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn spec_for_each<F: FnMut(Self::Item)>(mut self, mut f: F) {
                let end = self.n.min(self.iter.size());
                for i in 0..end {
                    // SAFETY: i < end <= self.iter.size() and we discard the iterator at the end
                    let val = unsafe { self.iter.__iterator_get_unchecked(i) };
                    f(val);
                }
            }
        *)
        Definition spec_for_each
            (I : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self I in
          match ε, τ, α with
          | [], [ F ], [ self; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let f := M.alloc (| f |) in
              M.read (|
                let~ end_ :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (| "core::cmp::Ord", Ty.path "usize", [], "min", [] |),
                      [
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            self,
                            "core::iter::adapters::take::Take",
                            "n"
                          |)
                        |);
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::iter::adapters::zip::TrustedRandomAccessNoCoerce",
                            I,
                            [],
                            "size",
                            []
                          |),
                          [
                            M.SubPointer.get_struct_record_field (|
                              self,
                              "core::iter::adapters::take::Take",
                              "iter"
                            |)
                          ]
                        |)
                      ]
                    |)
                  |) in
                M.use
                  (M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::collect::IntoIterator",
                          Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ],
                          [],
                          "into_iter",
                          []
                        |),
                        [
                          Value.StructRecord
                            "core::ops::range::Range"
                            [
                              ("start", Value.Integer IntegerKind.Usize 0);
                              ("end_", M.read (| end_ |))
                            ]
                        ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let iter := M.copy (| γ |) in
                          M.loop (|
                            ltac:(M.monadic
                              (let~ _ :=
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::iterator::Iterator",
                                        Ty.apply
                                          (Ty.path "core::ops::range::Range")
                                          []
                                          [ Ty.path "usize" ],
                                        [],
                                        "next",
                                        []
                                      |),
                                      [ iter ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (| M.read (| M.break (||) |) |)
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let i := M.copy (| γ0_0 |) in
                                        let~ val :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::iter::traits::iterator::Iterator",
                                                I,
                                                [],
                                                "__iterator_get_unchecked",
                                                []
                                              |),
                                              [
                                                M.SubPointer.get_struct_record_field (|
                                                  self,
                                                  "core::iter::adapters::take::Take",
                                                  "iter"
                                                |);
                                                M.read (| i |)
                                              ]
                                            |)
                                          |) in
                                        let~ _ :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::ops::function::FnMut",
                                                F,
                                                [ Ty.tuple [ Ty.associated ] ],
                                                "call_mut",
                                                []
                                              |),
                                              [ f; Value.Tuple [ M.read (| val |) ] ]
                                            |)
                                          |) in
                                        M.alloc (| Value.Tuple [] |)))
                                  ]
                                |) in
                              M.alloc (| Value.Tuple [] |)))
                          |)))
                    ]
                  |))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (I : Ty.t),
          M.IsTraitInstance
            "core::iter::adapters::take::SpecTake"
            (Self I)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("spec_fold", InstanceField.Method (spec_fold I));
              ("spec_for_each", InstanceField.Method (spec_for_each I))
            ].
      End Impl_core_iter_adapters_take_SpecTake_where_core_iter_traits_iterator_Iterator_I_where_core_iter_adapters_zip_TrustedRandomAccess_I_for_core_iter_adapters_take_Take_I.
      
      Module Impl_core_iter_traits_double_ended_DoubleEndedIterator_where_core_clone_Clone_T_for_core_iter_adapters_take_Take_core_iter_sources_repeat_Repeat_T.
        Definition Self (T : Ty.t) : Ty.t :=
          Ty.apply
            (Ty.path "core::iter::adapters::take::Take")
            []
            [ Ty.apply (Ty.path "core::iter::sources::repeat::Repeat") [] [ T ] ].
        
        (*
            fn next_back(&mut self) -> Option<Self::Item> {
                self.next()
            }
        *)
        Definition next_back (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self T in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::iterator::Iterator",
                  Ty.apply
                    (Ty.path "core::iter::adapters::take::Take")
                    []
                    [ Ty.apply (Ty.path "core::iter::sources::repeat::Repeat") [] [ T ] ],
                  [],
                  "next",
                  []
                |),
                [ M.read (| self |) ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
                self.nth(n)
            }
        *)
        Definition nth_back (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self T in
          match ε, τ, α with
          | [], [], [ self; n ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let n := M.alloc (| n |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::iterator::Iterator",
                  Ty.apply
                    (Ty.path "core::iter::adapters::take::Take")
                    []
                    [ Ty.apply (Ty.path "core::iter::sources::repeat::Repeat") [] [ T ] ],
                  [],
                  "nth",
                  []
                |),
                [ M.read (| self |); M.read (| n |) ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
            where
                Self: Sized,
                Fold: FnMut(Acc, Self::Item) -> R,
                R: Try<Output = Acc>,
            {
                self.try_fold(init, fold)
            }
        *)
        Definition try_rfold (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self T in
          match ε, τ, α with
          | [], [ Acc; Fold; R ], [ self; init; fold ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let fold := M.alloc (| fold |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::iterator::Iterator",
                  Ty.apply
                    (Ty.path "core::iter::adapters::take::Take")
                    []
                    [ Ty.apply (Ty.path "core::iter::sources::repeat::Repeat") [] [ T ] ],
                  [],
                  "try_fold",
                  [ Acc; Fold; R ]
                |),
                [ M.read (| self |); M.read (| init |); M.read (| fold |) ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
            where
                Self: Sized,
                Fold: FnMut(Acc, Self::Item) -> Acc,
            {
                self.fold(init, fold)
            }
        *)
        Definition rfold (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self T in
          match ε, τ, α with
          | [], [ Acc; Fold ], [ self; init; fold ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let fold := M.alloc (| fold |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::iterator::Iterator",
                  Ty.apply
                    (Ty.path "core::iter::adapters::take::Take")
                    []
                    [ Ty.apply (Ty.path "core::iter::sources::repeat::Repeat") [] [ T ] ],
                  [],
                  "fold",
                  [ Acc; Fold ]
                |),
                [ M.read (| self |); M.read (| init |); M.read (| fold |) ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
                self.advance_by(n)
            }
        *)
        Definition advance_back_by
            (T : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self T in
          match ε, τ, α with
          | [], [], [ self; n ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let n := M.alloc (| n |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::iterator::Iterator",
                  Ty.apply
                    (Ty.path "core::iter::adapters::take::Take")
                    []
                    [ Ty.apply (Ty.path "core::iter::sources::repeat::Repeat") [] [ T ] ],
                  [],
                  "advance_by",
                  []
                |),
                [ M.read (| self |); M.read (| n |) ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (T : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::double_ended::DoubleEndedIterator"
            (Self T)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("next_back", InstanceField.Method (next_back T));
              ("nth_back", InstanceField.Method (nth_back T));
              ("try_rfold", InstanceField.Method (try_rfold T));
              ("rfold", InstanceField.Method (rfold T));
              ("advance_back_by", InstanceField.Method (advance_back_by T))
            ].
      End Impl_core_iter_traits_double_ended_DoubleEndedIterator_where_core_clone_Clone_T_for_core_iter_adapters_take_Take_core_iter_sources_repeat_Repeat_T.
      
      Module Impl_core_iter_traits_exact_size_ExactSizeIterator_where_core_clone_Clone_T_for_core_iter_adapters_take_Take_core_iter_sources_repeat_Repeat_T.
        Definition Self (T : Ty.t) : Ty.t :=
          Ty.apply
            (Ty.path "core::iter::adapters::take::Take")
            []
            [ Ty.apply (Ty.path "core::iter::sources::repeat::Repeat") [] [ T ] ].
        
        (*
            fn len(&self) -> usize {
                self.n
            }
        *)
        Definition len (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self T in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.read (|
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::iter::adapters::take::Take",
                  "n"
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (T : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::exact_size::ExactSizeIterator"
            (Self T)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("len", InstanceField.Method (len T)) ].
      End Impl_core_iter_traits_exact_size_ExactSizeIterator_where_core_clone_Clone_T_for_core_iter_adapters_take_Take_core_iter_sources_repeat_Repeat_T.
      
      Module Impl_core_iter_traits_exact_size_ExactSizeIterator_where_core_ops_function_FnMut_F_Tuple__for_core_iter_adapters_take_Take_core_iter_sources_repeat_with_RepeatWith_F.
        Definition Self (F A : Ty.t) : Ty.t :=
          Ty.apply
            (Ty.path "core::iter::adapters::take::Take")
            []
            [ Ty.apply (Ty.path "core::iter::sources::repeat_with::RepeatWith") [] [ F ] ].
        
        (*
            fn len(&self) -> usize {
                self.n
            }
        *)
        Definition len (F A : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self F A in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.read (|
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::iter::adapters::take::Take",
                  "n"
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (F A : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::exact_size::ExactSizeIterator"
            (Self F A)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("len", InstanceField.Method (len F A)) ].
      End Impl_core_iter_traits_exact_size_ExactSizeIterator_where_core_ops_function_FnMut_F_Tuple__for_core_iter_adapters_take_Take_core_iter_sources_repeat_with_RepeatWith_F.
    End take.
  End adapters.
End iter.
