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

Module iter.
  Module adapters.
    Module cycle.
      (* StructRecord
        {
          name := "Cycle";
          const_params := [];
          ty_params := [ "I" ];
          fields := [ ("orig", I); ("iter", I) ];
        } *)
      
      Module Impl_core_clone_Clone_where_core_clone_Clone_I_for_core_iter_adapters_cycle_Cycle_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::cycle::Cycle") [] [ 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::cycle::Cycle"
                [
                  ("orig",
                    M.call_closure (|
                      M.get_trait_method (| "core::clone::Clone", I, [], "clone", [] |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::iter::adapters::cycle::Cycle",
                          "orig"
                        |)
                      ]
                    |));
                  ("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::cycle::Cycle",
                          "iter"
                        |)
                      ]
                    |))
                ]))
          | _, _, _ => 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_cycle_Cycle_I.
      
      Module Impl_core_fmt_Debug_where_core_fmt_Debug_I_for_core_iter_adapters_cycle_Cycle_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::cycle::Cycle") [] [ 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 "Cycle" |);
                  M.read (| Value.String "orig" |);
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::iter::adapters::cycle::Cycle",
                    "orig"
                  |);
                  M.read (| Value.String "iter" |);
                  M.alloc (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "core::iter::adapters::cycle::Cycle",
                      "iter"
                    |)
                  |)
                ]
              |)))
          | _, _, _ => 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_cycle_Cycle_I.
      
      Module Impl_core_iter_adapters_cycle_Cycle_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::cycle::Cycle") [] [ I ].
        
        (*
            pub(in crate::iter) fn new(iter: I) -> Cycle<I> {
                Cycle { orig: iter.clone(), iter }
            }
        *)
        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 ] =>
            ltac:(M.monadic
              (let iter := M.alloc (| iter |) in
              Value.StructRecord
                "core::iter::adapters::cycle::Cycle"
                [
                  ("orig",
                    M.call_closure (|
                      M.get_trait_method (| "core::clone::Clone", I, [], "clone", [] |),
                      [ iter ]
                    |));
                  ("iter", M.read (| iter |))
                ]))
          | _, _, _ => 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_cycle_Cycle_I.
      
      Module Impl_core_iter_traits_iterator_Iterator_where_core_clone_Clone_I_where_core_iter_traits_iterator_Iterator_I_for_core_iter_adapters_cycle_Cycle_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::cycle::Cycle") [] [ 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> {
                match self.iter.next() {
                    None => {
                        self.iter = self.orig.clone();
                        self.iter.next()
                    }
                    y => y,
                }
            }
        *)
        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 (|
                    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::cycle::Cycle",
                          "iter"
                        |)
                      ]
                    |)
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                        let~ _ :=
                          M.write (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::iter::adapters::cycle::Cycle",
                              "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::cycle::Cycle",
                                  "orig"
                                |)
                              ]
                            |)
                          |) 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::cycle::Cycle",
                                "iter"
                              |)
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let y := M.copy (| γ |) in
                        y))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn size_hint(&self) -> (usize, Option<usize>) {
                // the cycle iterator is either empty or infinite
                match self.orig.size_hint() {
                    sz @ (0, Some(0)) => sz,
                    (0, _) => (0, None),
                    _ => (usize::MAX, None),
                }
            }
        *)
        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.read (|
                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::cycle::Cycle",
                          "orig"
                        |)
                      ]
                    |)
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let sz := M.copy (| γ |) in
                        let γ1_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                        let γ1_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                        let _ :=
                          M.is_constant_or_break_match (|
                            M.read (| γ1_0 |),
                            Value.Integer IntegerKind.Usize 0
                          |) in
                        let γ2_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ1_1,
                            "core::option::Option::Some",
                            0
                          |) in
                        let _ :=
                          M.is_constant_or_break_match (|
                            M.read (| γ2_0 |),
                            Value.Integer IntegerKind.Usize 0
                          |) in
                        sz));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                        let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                        let _ :=
                          M.is_constant_or_break_match (|
                            M.read (| γ0_0 |),
                            Value.Integer IntegerKind.Usize 0
                          |) in
                        M.alloc (|
                          Value.Tuple
                            [
                              Value.Integer IntegerKind.Usize 0;
                              Value.StructTuple "core::option::Option::None" []
                            ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (M.alloc (|
                          Value.Tuple
                            [
                              M.read (| M.get_constant (| "core::num::MAX" |) |);
                              Value.StructTuple "core::option::Option::None" []
                            ]
                        |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
            where
                F: FnMut(Acc, Self::Item) -> R,
                R: Try<Output = Acc>,
            {
                // fully iterate the current iterator. this is necessary because
                // `self.iter` may be empty even when `self.orig` isn't
                acc = self.iter.try_fold(acc, &mut f)?;
                self.iter = self.orig.clone();
        
                // complete a full cycle, keeping track of whether the cycled
                // iterator is empty or not. we need to return early in case
                // of an empty iterator to prevent an infinite loop
                let mut is_empty = true;
                acc = self.iter.try_fold(acc, |acc, x| {
                    is_empty = false;
                    f(acc, x)
                })?;
        
                if is_empty {
                    return try { acc };
                }
        
                loop {
                    self.iter = self.orig.clone();
                    acc = self.iter.try_fold(acc, &mut f)?;
                }
            }
        *)
        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; F; R ], [ self; acc; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let acc := M.alloc (| acc |) in
              let f := M.alloc (| f |) in
              M.catch_return (|
                ltac:(M.monadic
                  (M.read (|
                    let~ _ :=
                      M.write (|
                        acc,
                        M.read (|
                          M.match_operator (|
                            M.alloc (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::ops::try_trait::Try",
                                  R,
                                  [],
                                  "branch",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::iter::traits::iterator::Iterator",
                                      I,
                                      [],
                                      "try_fold",
                                      [ Acc; Ty.apply (Ty.path "&mut") [] [ F ]; R ]
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::iter::adapters::cycle::Cycle",
                                        "iter"
                                      |);
                                      M.read (| acc |);
                                      f
                                    ]
                                  |)
                                ]
                              |)
                            |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ0_0 :=
                                    M.SubPointer.get_struct_tuple_field (|
                                      γ,
                                      "core::ops::control_flow::ControlFlow::Break",
                                      0
                                    |) in
                                  let residual := M.copy (| γ0_0 |) in
                                  M.alloc (|
                                    M.never_to_any (|
                                      M.read (|
                                        M.return_ (|
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::ops::try_trait::FromResidual",
                                              R,
                                              [ Ty.associated ],
                                              "from_residual",
                                              []
                                            |),
                                            [ M.read (| residual |) ]
                                          |)
                                        |)
                                      |)
                                    |)
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ0_0 :=
                                    M.SubPointer.get_struct_tuple_field (|
                                      γ,
                                      "core::ops::control_flow::ControlFlow::Continue",
                                      0
                                    |) in
                                  let val := M.copy (| γ0_0 |) in
                                  val))
                            ]
                          |)
                        |)
                      |) in
                    let~ _ :=
                      M.write (|
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::iter::adapters::cycle::Cycle",
                          "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::cycle::Cycle",
                              "orig"
                            |)
                          ]
                        |)
                      |) in
                    let~ is_empty := M.alloc (| Value.Bool true |) in
                    let~ _ :=
                      M.write (|
                        acc,
                        M.read (|
                          M.match_operator (|
                            M.alloc (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::ops::try_trait::Try",
                                  R,
                                  [],
                                  "branch",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::iter::traits::iterator::Iterator",
                                      I,
                                      [],
                                      "try_fold",
                                      [ Acc; Ty.function [ Ty.tuple [ Acc; Ty.associated ] ] R; R ]
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::iter::adapters::cycle::Cycle",
                                        "iter"
                                      |);
                                      M.read (| acc |);
                                      M.closure
                                        (fun γ =>
                                          ltac:(M.monadic
                                            match γ with
                                            | [ α0; α1 ] =>
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  M.alloc (| α0 |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let acc := M.copy (| γ |) in
                                                        M.match_operator (|
                                                          M.alloc (| α1 |),
                                                          [
                                                            fun γ =>
                                                              ltac:(M.monadic
                                                                (let x := M.copy (| γ |) in
                                                                M.read (|
                                                                  let~ _ :=
                                                                    M.write (|
                                                                      is_empty,
                                                                      Value.Bool false
                                                                    |) in
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_trait_method (|
                                                                        "core::ops::function::FnMut",
                                                                        F,
                                                                        [
                                                                          Ty.tuple
                                                                            [ Acc; Ty.associated ]
                                                                        ],
                                                                        "call_mut",
                                                                        []
                                                                      |),
                                                                      [
                                                                        f;
                                                                        Value.Tuple
                                                                          [
                                                                            M.read (| acc |);
                                                                            M.read (| x |)
                                                                          ]
                                                                      ]
                                                                    |)
                                                                  |)
                                                                |)))
                                                          ]
                                                        |)))
                                                  ]
                                                |)))
                                            | _ => M.impossible "wrong number of arguments"
                                            end))
                                    ]
                                  |)
                                ]
                              |)
                            |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ0_0 :=
                                    M.SubPointer.get_struct_tuple_field (|
                                      γ,
                                      "core::ops::control_flow::ControlFlow::Break",
                                      0
                                    |) in
                                  let residual := M.copy (| γ0_0 |) in
                                  M.alloc (|
                                    M.never_to_any (|
                                      M.read (|
                                        M.return_ (|
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::ops::try_trait::FromResidual",
                                              R,
                                              [ Ty.associated ],
                                              "from_residual",
                                              []
                                            |),
                                            [ M.read (| residual |) ]
                                          |)
                                        |)
                                      |)
                                    |)
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ0_0 :=
                                    M.SubPointer.get_struct_tuple_field (|
                                      γ,
                                      "core::ops::control_flow::ControlFlow::Continue",
                                      0
                                    |) in
                                  let val := M.copy (| γ0_0 |) in
                                  val))
                            ]
                          |)
                        |)
                      |) in
                    let~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ := M.use is_empty in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    M.return_ (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::ops::try_trait::Try",
                                          R,
                                          [],
                                          "from_output",
                                          []
                                        |),
                                        [ M.read (| acc |) ]
                                      |)
                                    |)
                                  |)
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    M.alloc (|
                      M.never_to_any (|
                        M.read (|
                          M.loop (|
                            ltac:(M.monadic
                              (let~ _ :=
                                M.write (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::cycle::Cycle",
                                    "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::cycle::Cycle",
                                        "orig"
                                      |)
                                    ]
                                  |)
                                |) in
                              let~ _ :=
                                M.write (|
                                  acc,
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::ops::try_trait::Try",
                                            R,
                                            [],
                                            "branch",
                                            []
                                          |),
                                          [
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::iter::traits::iterator::Iterator",
                                                I,
                                                [],
                                                "try_fold",
                                                [ Acc; Ty.apply (Ty.path "&mut") [] [ F ]; R ]
                                              |),
                                              [
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::iter::adapters::cycle::Cycle",
                                                  "iter"
                                                |);
                                                M.read (| acc |);
                                                f
                                              ]
                                            |)
                                          ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::ops::control_flow::ControlFlow::Break",
                                                0
                                              |) in
                                            let residual := M.copy (| γ0_0 |) in
                                            M.alloc (|
                                              M.never_to_any (|
                                                M.read (|
                                                  M.return_ (|
                                                    M.call_closure (|
                                                      M.get_trait_method (|
                                                        "core::ops::try_trait::FromResidual",
                                                        R,
                                                        [ Ty.associated ],
                                                        "from_residual",
                                                        []
                                                      |),
                                                      [ M.read (| residual |) ]
                                                    |)
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::ops::control_flow::ControlFlow::Continue",
                                                0
                                              |) in
                                            let val := M.copy (| γ0_0 |) in
                                            val))
                                      ]
                                    |)
                                  |)
                                |) in
                              M.alloc (| Value.Tuple [] |)))
                          |)
                        |)
                      |)
                    |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
                let mut n = match self.iter.advance_by(n) {
                    Ok(()) => return Ok(()),
                    Err(rem) => rem.get(),
                };
        
                while n > 0 {
                    self.iter = self.orig.clone();
                    n = match self.iter.advance_by(n) {
                        Ok(()) => return Ok(()),
                        e @ Err(rem) if rem.get() == n => return e,
                        Err(rem) => rem.get(),
                    };
                }
        
                NonZero::new(n).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.catch_return (|
                ltac:(M.monadic
                  (M.read (|
                    let~ n :=
                      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::cycle::Cycle",
                                  "iter"
                                |);
                                M.read (| n |)
                              ]
                            |)
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::result::Result::Ok",
                                    0
                                  |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.read (|
                                      M.return_ (|
                                        Value.StructTuple
                                          "core::result::Result::Ok"
                                          [ Value.Tuple [] ]
                                      |)
                                    |)
                                  |)
                                |)));
                            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~ _ :=
                      M.loop (|
                        ltac:(M.monadic
                          (M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ :=
                                    M.use
                                      (M.alloc (|
                                        BinOp.gt (|
                                          M.read (| n |),
                                          Value.Integer IntegerKind.Usize 0
                                        |)
                                      |)) in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::iter::adapters::cycle::Cycle",
                                        "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::cycle::Cycle",
                                            "orig"
                                          |)
                                        ]
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      n,
                                      M.read (|
                                        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::cycle::Cycle",
                                                  "iter"
                                                |);
                                                M.read (| n |)
                                              ]
                                            |)
                                          |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ0_0 :=
                                                  M.SubPointer.get_struct_tuple_field (|
                                                    γ,
                                                    "core::result::Result::Ok",
                                                    0
                                                  |) in
                                                M.alloc (|
                                                  M.never_to_any (|
                                                    M.read (|
                                                      M.return_ (|
                                                        Value.StructTuple
                                                          "core::result::Result::Ok"
                                                          [ Value.Tuple [] ]
                                                      |)
                                                    |)
                                                  |)
                                                |)));
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let e := M.copy (| γ |) in
                                                let γ1_0 :=
                                                  M.SubPointer.get_struct_tuple_field (|
                                                    γ,
                                                    "core::result::Result::Err",
                                                    0
                                                  |) in
                                                let rem := M.copy (| γ1_0 |) in
                                                let γ :=
                                                  M.alloc (|
                                                    BinOp.eq (|
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.apply
                                                            (Ty.path "core::num::nonzero::NonZero")
                                                            []
                                                            [ Ty.path "usize" ],
                                                          "get",
                                                          []
                                                        |),
                                                        [ M.read (| rem |) ]
                                                      |),
                                                      M.read (| n |)
                                                    |)
                                                  |) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                M.alloc (|
                                                  M.never_to_any (|
                                                    M.read (| M.return_ (| M.read (| e |) |) |)
                                                  |)
                                                |)));
                                            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
                                  M.alloc (| Value.Tuple [] |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (M.alloc (|
                                    M.never_to_any (|
                                      M.read (|
                                        let~ _ :=
                                          M.alloc (|
                                            M.never_to_any (| M.read (| M.break (||) |) |)
                                          |) in
                                        M.alloc (| Value.Tuple [] |)
                                      |)
                                    |)
                                  |)))
                            ]
                          |)))
                      |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "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",
                              []
                            |),
                            [ M.read (| n |) ]
                          |);
                          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));
              ("size_hint", InstanceField.Method (size_hint I));
              ("try_fold", InstanceField.Method (try_fold I));
              ("advance_by", InstanceField.Method (advance_by I))
            ].
      End Impl_core_iter_traits_iterator_Iterator_where_core_clone_Clone_I_where_core_iter_traits_iterator_Iterator_I_for_core_iter_adapters_cycle_Cycle_I.
      
      Module Impl_core_iter_traits_marker_FusedIterator_where_core_clone_Clone_I_where_core_iter_traits_iterator_Iterator_I_for_core_iter_adapters_cycle_Cycle_I.
        Definition Self (I : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::cycle::Cycle") [] [ 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_clone_Clone_I_where_core_iter_traits_iterator_Iterator_I_for_core_iter_adapters_cycle_Cycle_I.
    End cycle.
  End adapters.
End iter.
