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

Module iter.
  Module adapters.
    Module chain.
      (* StructRecord
        {
          name := "Chain";
          const_params := [];
          ty_params := [ "A"; "B" ];
          fields :=
            [
              ("a", Ty.apply (Ty.path "core::option::Option") [] [ A ]);
              ("b", Ty.apply (Ty.path "core::option::Option") [] [ B ])
            ];
        } *)
      
      Module Impl_core_clone_Clone_where_core_clone_Clone_A_where_core_clone_Clone_B_for_core_iter_adapters_chain_Chain_A_B.
        Definition Self (A B : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::chain::Chain") [] [ A; B ].
        
        (* Clone *)
        Definition clone (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              Value.StructRecord
                "core::iter::adapters::chain::Chain"
                [
                  ("a",
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::clone::Clone",
                        Ty.apply (Ty.path "core::option::Option") [] [ A ],
                        [],
                        "clone",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::iter::adapters::chain::Chain",
                          "a"
                        |)
                      ]
                    |));
                  ("b",
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::clone::Clone",
                        Ty.apply (Ty.path "core::option::Option") [] [ B ],
                        [],
                        "clone",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::iter::adapters::chain::Chain",
                          "b"
                        |)
                      ]
                    |))
                ]))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (A B : Ty.t),
          M.IsTraitInstance
            "core::clone::Clone"
            (Self A B)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("clone", InstanceField.Method (clone A B)) ].
      End Impl_core_clone_Clone_where_core_clone_Clone_A_where_core_clone_Clone_B_for_core_iter_adapters_chain_Chain_A_B.
      
      Module Impl_core_fmt_Debug_where_core_fmt_Debug_A_where_core_fmt_Debug_B_for_core_iter_adapters_chain_Chain_A_B.
        Definition Self (A B : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::chain::Chain") [] [ A; B ].
        
        (* Debug *)
        Definition fmt (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B 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 "Chain" |);
                  M.read (| Value.String "a" |);
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::iter::adapters::chain::Chain",
                    "a"
                  |);
                  M.read (| Value.String "b" |);
                  M.alloc (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "core::iter::adapters::chain::Chain",
                      "b"
                    |)
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (A B : Ty.t),
          M.IsTraitInstance
            "core::fmt::Debug"
            (Self A B)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("fmt", InstanceField.Method (fmt A B)) ].
      End Impl_core_fmt_Debug_where_core_fmt_Debug_A_where_core_fmt_Debug_B_for_core_iter_adapters_chain_Chain_A_B.
      
      Module Impl_core_iter_adapters_chain_Chain_A_B.
        Definition Self (A B : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::chain::Chain") [] [ A; B ].
        
        (*
            pub(in super::super) fn new(a: A, b: B) -> Chain<A, B> {
                Chain { a: Some(a), b: Some(b) }
            }
        *)
        Definition new (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [], [ a; b ] =>
            ltac:(M.monadic
              (let a := M.alloc (| a |) in
              let b := M.alloc (| b |) in
              Value.StructRecord
                "core::iter::adapters::chain::Chain"
                [
                  ("a", Value.StructTuple "core::option::Option::Some" [ M.read (| a |) ]);
                  ("b", Value.StructTuple "core::option::Option::Some" [ M.read (| b |) ])
                ]))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_new :
          forall (A B : Ty.t),
          M.IsAssociatedFunction (Self A B) "new" (new A B).
      End Impl_core_iter_adapters_chain_Chain_A_B.
      
      (*
      pub fn chain<A, B>(a: A, b: B) -> Chain<A::IntoIter, B::IntoIter>
      where
          A: IntoIterator,
          B: IntoIterator<Item = A::Item>,
      {
          Chain::new(a.into_iter(), b.into_iter())
      }
      *)
      Definition chain (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ A; B ], [ a; b ] =>
          ltac:(M.monadic
            (let a := M.alloc (| a |) in
            let b := M.alloc (| b |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply
                  (Ty.path "core::iter::adapters::chain::Chain")
                  []
                  [ Ty.associated; Ty.associated ],
                "new",
                []
              |),
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::iter::traits::collect::IntoIterator",
                    A,
                    [],
                    "into_iter",
                    []
                  |),
                  [ M.read (| a |) ]
                |);
                M.call_closure (|
                  M.get_trait_method (|
                    "core::iter::traits::collect::IntoIterator",
                    B,
                    [],
                    "into_iter",
                    []
                  |),
                  [ M.read (| b |) ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Function_chain : M.IsFunction "core::iter::adapters::chain::chain" chain.
      
      Module Impl_core_iter_traits_iterator_Iterator_where_core_iter_traits_iterator_Iterator_A_where_core_iter_traits_iterator_Iterator_B_for_core_iter_adapters_chain_Chain_A_B.
        Definition Self (A B : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::chain::Chain") [] [ A; B ].
        
        (*     type Item = A::Item; *)
        Definition _Item (A B : Ty.t) : Ty.t := Ty.associated.
        
        (*
            fn next(&mut self) -> Option<A::Item> {
                and_then_or_clear(&mut self.a, Iterator::next).or_else(|| self.b.as_mut()?.next())
            }
        *)
        Definition next (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ],
                  "or_else",
                  [
                    Ty.function
                      [ Ty.tuple [] ]
                      (Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ])
                  ]
                |),
                [
                  M.call_closure (|
                    M.get_function (|
                      "core::iter::adapters::chain::and_then_or_clear",
                      [
                        A;
                        Ty.associated;
                        Ty.function
                          [ Ty.apply (Ty.path "&mut") [] [ A ] ]
                          (Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ])
                      ]
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::iter::adapters::chain::Chain",
                        "a"
                      |);
                      M.get_trait_method (|
                        "core::iter::traits::iterator::Iterator",
                        A,
                        [],
                        "next",
                        []
                      |)
                    ]
                  |);
                  M.closure
                    (fun γ =>
                      ltac:(M.monadic
                        match γ with
                        | [ α0 ] =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| α0 |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::iterator::Iterator",
                                        B,
                                        [],
                                        "next",
                                        []
                                      |),
                                      [
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::try_trait::Try",
                                                  Ty.apply
                                                    (Ty.path "core::option::Option")
                                                    []
                                                    [ Ty.apply (Ty.path "&mut") [] [ B ] ],
                                                  [],
                                                  "branch",
                                                  []
                                                |),
                                                [
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "core::option::Option")
                                                        []
                                                        [ B ],
                                                      "as_mut",
                                                      []
                                                    |),
                                                    [
                                                      M.SubPointer.get_struct_record_field (|
                                                        M.read (| self |),
                                                        "core::iter::adapters::chain::Chain",
                                                        "b"
                                                      |)
                                                    ]
                                                  |)
                                                ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::ops::control_flow::ControlFlow::Break",
                                                      0
                                                    |) in
                                                  let residual := M.copy (| γ0_0 |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          M.call_closure (|
                                                            M.get_trait_method (|
                                                              "core::ops::try_trait::FromResidual",
                                                              Ty.apply
                                                                (Ty.path "core::option::Option")
                                                                []
                                                                [ Ty.associated ],
                                                              [
                                                                Ty.apply
                                                                  (Ty.path "core::option::Option")
                                                                  []
                                                                  [
                                                                    Ty.path
                                                                      "core::convert::Infallible"
                                                                  ]
                                                              ],
                                                              "from_residual",
                                                              []
                                                            |),
                                                            [ M.read (| residual |) ]
                                                          |)
                                                        |)
                                                      |)
                                                    |)
                                                  |)));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::ops::control_flow::ControlFlow::Continue",
                                                      0
                                                    |) in
                                                  let val := M.copy (| γ0_0 |) in
                                                  val))
                                            ]
                                          |)
                                        |)
                                      ]
                                    |)))
                              ]
                            |)))
                        | _ => M.impossible "wrong number of arguments"
                        end))
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn count(self) -> usize {
                let a_count = match self.a {
                    Some(a) => a.count(),
                    None => 0,
                };
                let b_count = match self.b {
                    Some(b) => b.count(),
                    None => 0,
                };
                a_count + b_count
            }
        *)
        Definition count (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.read (|
                let~ a_count :=
                  M.copy (|
                    M.match_operator (|
                      M.SubPointer.get_struct_record_field (|
                        self,
                        "core::iter::adapters::chain::Chain",
                        "a"
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let a := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::iterator::Iterator",
                                  A,
                                  [],
                                  "count",
                                  []
                                |),
                                [ M.read (| a |) ]
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                            M.alloc (| Value.Integer IntegerKind.Usize 0 |)))
                      ]
                    |)
                  |) in
                let~ b_count :=
                  M.copy (|
                    M.match_operator (|
                      M.SubPointer.get_struct_record_field (|
                        self,
                        "core::iter::adapters::chain::Chain",
                        "b"
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let b := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::iterator::Iterator",
                                  B,
                                  [],
                                  "count",
                                  []
                                |),
                                [ M.read (| b |) ]
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                            M.alloc (| Value.Integer IntegerKind.Usize 0 |)))
                      ]
                    |)
                  |) in
                M.alloc (| BinOp.Wrap.add (| M.read (| a_count |), M.read (| b_count |) |) |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
            where
                Self: Sized,
                F: FnMut(Acc, Self::Item) -> R,
                R: Try<Output = Acc>,
            {
                if let Some(ref mut a) = self.a {
                    acc = a.try_fold(acc, &mut f)?;
                    self.a = None;
                }
                if let Some(ref mut b) = self.b {
                    acc = b.try_fold(acc, f)?;
                    // we don't fuse the second iterator
                }
                try { acc }
            }
        *)
        Definition try_fold
            (A B : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self A B 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.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::chain::Chain",
                                  "a"
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let a := M.alloc (| γ0_0 |) 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",
                                                A,
                                                [],
                                                "try_fold",
                                                [ Acc; Ty.apply (Ty.path "&mut") [] [ F ]; R ]
                                              |),
                                              [ M.read (| a |); 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::chain::Chain",
                                    "a"
                                  |),
                                  Value.StructTuple "core::option::Option::None" []
                                |) in
                              M.alloc (| Value.Tuple [] |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    let~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::chain::Chain",
                                  "b"
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let b := M.alloc (| γ0_0 |) 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",
                                                B,
                                                [],
                                                "try_fold",
                                                [ Acc; F; R ]
                                              |),
                                              [ M.read (| b |); M.read (| acc |); M.read (| 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 [] |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::ops::try_trait::Try",
                          R,
                          [],
                          "from_output",
                          []
                        |),
                        [ M.read (| acc |) ]
                      |)
                    |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn fold<Acc, F>(self, mut acc: Acc, mut f: F) -> Acc
            where
                F: FnMut(Acc, Self::Item) -> Acc,
            {
                if let Some(a) = self.a {
                    acc = a.fold(acc, &mut f);
                }
                if let Some(b) = self.b {
                    acc = b.fold(acc, f);
                }
                acc
            }
        *)
        Definition fold (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [ Acc; F ], [ 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.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.SubPointer.get_struct_record_field (|
                              self,
                              "core::iter::adapters::chain::Chain",
                              "a"
                            |) in
                          let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let a := M.copy (| γ0_0 |) in
                          let~ _ :=
                            M.write (|
                              acc,
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::iterator::Iterator",
                                  A,
                                  [],
                                  "fold",
                                  [ Acc; Ty.apply (Ty.path "&mut") [] [ F ] ]
                                |),
                                [ M.read (| a |); M.read (| acc |); f ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.SubPointer.get_struct_record_field (|
                              self,
                              "core::iter::adapters::chain::Chain",
                              "b"
                            |) in
                          let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let b := M.copy (| γ0_0 |) in
                          let~ _ :=
                            M.write (|
                              acc,
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::iterator::Iterator",
                                  B,
                                  [],
                                  "fold",
                                  [ Acc; F ]
                                |),
                                [ M.read (| b |); M.read (| acc |); M.read (| f |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                acc
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn advance_by(&mut self, mut n: usize) -> Result<(), NonZero<usize>> {
                if let Some(ref mut a) = self.a {
                    n = match a.advance_by(n) {
                        Ok(()) => return Ok(()),
                        Err(k) => k.get(),
                    };
                    self.a = None;
                }
        
                if let Some(ref mut b) = self.b {
                    return b.advance_by(n);
                    // we don't fuse the second iterator
                }
        
                NonZero::new(n).map_or(Ok(()), Err)
            }
        *)
        Definition advance_by
            (A B : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self A B 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~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::chain::Chain",
                                  "a"
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let a := M.alloc (| γ0_0 |) in
                              let~ _ :=
                                M.write (|
                                  n,
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            A,
                                            [],
                                            "advance_by",
                                            []
                                          |),
                                          [ M.read (| a |); 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 k := 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 (| k |) ]
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                |) in
                              let~ _ :=
                                M.write (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::chain::Chain",
                                    "a"
                                  |),
                                  Value.StructTuple "core::option::Option::None" []
                                |) in
                              M.alloc (| Value.Tuple [] |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    let~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::chain::Chain",
                                  "b"
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let b := M.alloc (| γ0_0 |) in
                              M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    M.return_ (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::iter::traits::iterator::Iterator",
                                          B,
                                          [],
                                          "advance_by",
                                          []
                                        |),
                                        [ M.read (| b |); M.read (| n |) ]
                                      |)
                                    |)
                                  |)
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (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.
        
        (*
            fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
                if let Some(ref mut a) = self.a {
                    n = match a.advance_by(n) {
                        Ok(()) => match a.next() {
                            None => 0,
                            x => return x,
                        },
                        Err(k) => k.get(),
                    };
        
                    self.a = None;
                }
        
                self.b.as_mut()?.nth(n)
            }
        *)
        Definition nth (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B 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~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::chain::Chain",
                                  "a"
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let a := M.alloc (| γ0_0 |) in
                              let~ _ :=
                                M.write (|
                                  n,
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            A,
                                            [],
                                            "advance_by",
                                            []
                                          |),
                                          [ M.read (| a |); M.read (| n |) ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::result::Result::Ok",
                                                0
                                              |) in
                                            M.match_operator (|
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::iter::traits::iterator::Iterator",
                                                    A,
                                                    [],
                                                    "next",
                                                    []
                                                  |),
                                                  [ M.read (| a |) ]
                                                |)
                                              |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let _ :=
                                                      M.is_struct_tuple (|
                                                        γ,
                                                        "core::option::Option::None"
                                                      |) in
                                                    M.alloc (|
                                                      Value.Integer IntegerKind.Usize 0
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let x := M.copy (| γ |) in
                                                    M.alloc (|
                                                      M.never_to_any (|
                                                        M.read (| M.return_ (| M.read (| x |) |) |)
                                                      |)
                                                    |)))
                                              ]
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::result::Result::Err",
                                                0
                                              |) in
                                            let k := 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 (| k |) ]
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                |) in
                              let~ _ :=
                                M.write (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::chain::Chain",
                                    "a"
                                  |),
                                  Value.StructTuple "core::option::Option::None" []
                                |) in
                              M.alloc (| Value.Tuple [] |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          B,
                          [],
                          "nth",
                          []
                        |),
                        [
                          M.read (|
                            M.match_operator (|
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::ops::try_trait::Try",
                                    Ty.apply
                                      (Ty.path "core::option::Option")
                                      []
                                      [ Ty.apply (Ty.path "&mut") [] [ B ] ],
                                    [],
                                    "branch",
                                    []
                                  |),
                                  [
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "core::option::Option") [] [ B ],
                                        "as_mut",
                                        []
                                      |),
                                      [
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::iter::adapters::chain::Chain",
                                          "b"
                                        |)
                                      ]
                                    |)
                                  ]
                                |)
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::ops::control_flow::ControlFlow::Break",
                                        0
                                      |) in
                                    let residual := M.copy (| γ0_0 |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::ops::try_trait::FromResidual",
                                                Ty.apply
                                                  (Ty.path "core::option::Option")
                                                  []
                                                  [ Ty.associated ],
                                                [
                                                  Ty.apply
                                                    (Ty.path "core::option::Option")
                                                    []
                                                    [ Ty.path "core::convert::Infallible" ]
                                                ],
                                                "from_residual",
                                                []
                                              |),
                                              [ M.read (| residual |) ]
                                            |)
                                          |)
                                        |)
                                      |)
                                    |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::ops::control_flow::ControlFlow::Continue",
                                        0
                                      |) in
                                    let val := M.copy (| γ0_0 |) in
                                    val))
                              ]
                            |)
                          |);
                          M.read (| n |)
                        ]
                      |)
                    |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
            where
                P: FnMut(&Self::Item) -> bool,
            {
                and_then_or_clear(&mut self.a, |a| a.find(&mut predicate))
                    .or_else(|| self.b.as_mut()?.find(predicate))
            }
        *)
        Definition find (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [ P ], [ self; predicate ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let predicate := M.alloc (| predicate |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ],
                  "or_else",
                  [
                    Ty.function
                      [ Ty.tuple [] ]
                      (Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ])
                  ]
                |),
                [
                  M.call_closure (|
                    M.get_function (|
                      "core::iter::adapters::chain::and_then_or_clear",
                      [
                        A;
                        Ty.associated;
                        Ty.function
                          [ Ty.tuple [ Ty.apply (Ty.path "&mut") [] [ A ] ] ]
                          (Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ])
                      ]
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::iter::adapters::chain::Chain",
                        "a"
                      |);
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let a := M.copy (| γ |) in
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            A,
                                            [],
                                            "find",
                                            [ Ty.apply (Ty.path "&mut") [] [ P ] ]
                                          |),
                                          [ M.read (| a |); predicate ]
                                        |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    ]
                  |);
                  M.closure
                    (fun γ =>
                      ltac:(M.monadic
                        match γ with
                        | [ α0 ] =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| α0 |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::iterator::Iterator",
                                        B,
                                        [],
                                        "find",
                                        [ P ]
                                      |),
                                      [
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::try_trait::Try",
                                                  Ty.apply
                                                    (Ty.path "core::option::Option")
                                                    []
                                                    [ Ty.apply (Ty.path "&mut") [] [ B ] ],
                                                  [],
                                                  "branch",
                                                  []
                                                |),
                                                [
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "core::option::Option")
                                                        []
                                                        [ B ],
                                                      "as_mut",
                                                      []
                                                    |),
                                                    [
                                                      M.SubPointer.get_struct_record_field (|
                                                        M.read (| self |),
                                                        "core::iter::adapters::chain::Chain",
                                                        "b"
                                                      |)
                                                    ]
                                                  |)
                                                ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::ops::control_flow::ControlFlow::Break",
                                                      0
                                                    |) in
                                                  let residual := M.copy (| γ0_0 |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          M.call_closure (|
                                                            M.get_trait_method (|
                                                              "core::ops::try_trait::FromResidual",
                                                              Ty.apply
                                                                (Ty.path "core::option::Option")
                                                                []
                                                                [ Ty.associated ],
                                                              [
                                                                Ty.apply
                                                                  (Ty.path "core::option::Option")
                                                                  []
                                                                  [
                                                                    Ty.path
                                                                      "core::convert::Infallible"
                                                                  ]
                                                              ],
                                                              "from_residual",
                                                              []
                                                            |),
                                                            [ M.read (| residual |) ]
                                                          |)
                                                        |)
                                                      |)
                                                    |)
                                                  |)));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::ops::control_flow::ControlFlow::Continue",
                                                      0
                                                    |) in
                                                  let val := M.copy (| γ0_0 |) in
                                                  val))
                                            ]
                                          |)
                                        |);
                                        M.read (| predicate |)
                                      ]
                                    |)))
                              ]
                            |)))
                        | _ => M.impossible "wrong number of arguments"
                        end))
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn last(self) -> Option<A::Item> {
                // Must exhaust a before b.
                let a_last = self.a.and_then(Iterator::last);
                let b_last = self.b.and_then(Iterator::last);
                b_last.or(a_last)
            }
        *)
        Definition last (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.read (|
                let~ a_last :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "core::option::Option") [] [ A ],
                        "and_then",
                        [
                          Ty.associated;
                          Ty.function
                            [ A ]
                            (Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ])
                        ]
                      |),
                      [
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            self,
                            "core::iter::adapters::chain::Chain",
                            "a"
                          |)
                        |);
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          A,
                          [],
                          "last",
                          []
                        |)
                      ]
                    |)
                  |) in
                let~ b_last :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "core::option::Option") [] [ B ],
                        "and_then",
                        [
                          Ty.associated;
                          Ty.function
                            [ B ]
                            (Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ])
                        ]
                      |),
                      [
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            self,
                            "core::iter::adapters::chain::Chain",
                            "b"
                          |)
                        |);
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          B,
                          [],
                          "last",
                          []
                        |)
                      ]
                    |)
                  |) in
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ],
                      "or",
                      []
                    |),
                    [ M.read (| b_last |); M.read (| a_last |) ]
                  |)
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn size_hint(&self) -> (usize, Option<usize>) {
                match self {
                    Chain { a: Some(a), b: Some(b) } => {
                        let (a_lower, a_upper) = a.size_hint();
                        let (b_lower, b_upper) = b.size_hint();
        
                        let lower = a_lower.saturating_add(b_lower);
        
                        let upper = match (a_upper, b_upper) {
                            (Some(x), Some(y)) => x.checked_add(y),
                            _ => None,
                        };
        
                        (lower, upper)
                    }
                    Chain { a: Some(a), b: None } => a.size_hint(),
                    Chain { a: None, b: Some(b) } => b.size_hint(),
                    Chain { a: None, b: None } => (0, Some(0)),
                }
            }
        *)
        Definition size_hint
            (A B : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.read (|
                M.match_operator (|
                  self,
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let γ1_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "core::iter::adapters::chain::Chain",
                            "a"
                          |) in
                        let γ1_1 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "core::iter::adapters::chain::Chain",
                            "b"
                          |) in
                        let γ2_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ1_0,
                            "core::option::Option::Some",
                            0
                          |) in
                        let a := M.alloc (| γ2_0 |) in
                        let γ2_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ1_1,
                            "core::option::Option::Some",
                            0
                          |) in
                        let b := M.alloc (| γ2_0 |) in
                        M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::iterator::Iterator",
                                A,
                                [],
                                "size_hint",
                                []
                              |),
                              [ M.read (| a |) ]
                            |)
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                let a_lower := M.copy (| γ0_0 |) in
                                let a_upper := M.copy (| γ0_1 |) in
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::iterator::Iterator",
                                        B,
                                        [],
                                        "size_hint",
                                        []
                                      |),
                                      [ M.read (| b |) ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                        let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                        let b_lower := M.copy (| γ0_0 |) in
                                        let b_upper := M.copy (| γ0_1 |) in
                                        let~ lower :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "usize",
                                                "saturating_add",
                                                []
                                              |),
                                              [ M.read (| a_lower |); M.read (| b_lower |) ]
                                            |)
                                          |) in
                                        let~ upper :=
                                          M.copy (|
                                            M.match_operator (|
                                              M.alloc (|
                                                Value.Tuple
                                                  [ M.read (| a_upper |); M.read (| b_upper |) ]
                                              |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ0_0 :=
                                                      M.SubPointer.get_tuple_field (| γ, 0 |) in
                                                    let γ0_1 :=
                                                      M.SubPointer.get_tuple_field (| γ, 1 |) in
                                                    let γ1_0 :=
                                                      M.SubPointer.get_struct_tuple_field (|
                                                        γ0_0,
                                                        "core::option::Option::Some",
                                                        0
                                                      |) in
                                                    let x := M.copy (| γ1_0 |) in
                                                    let γ1_0 :=
                                                      M.SubPointer.get_struct_tuple_field (|
                                                        γ0_1,
                                                        "core::option::Option::Some",
                                                        0
                                                      |) in
                                                    let y := M.copy (| γ1_0 |) in
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.path "usize",
                                                          "checked_add",
                                                          []
                                                        |),
                                                        [ M.read (| x |); M.read (| y |) ]
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (M.alloc (|
                                                      Value.StructTuple
                                                        "core::option::Option::None"
                                                        []
                                                    |)))
                                              ]
                                            |)
                                          |) in
                                        M.alloc (|
                                          Value.Tuple [ M.read (| lower |); M.read (| upper |) ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let γ1_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "core::iter::adapters::chain::Chain",
                            "a"
                          |) in
                        let γ1_1 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "core::iter::adapters::chain::Chain",
                            "b"
                          |) in
                        let γ2_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ1_0,
                            "core::option::Option::Some",
                            0
                          |) in
                        let a := M.alloc (| γ2_0 |) in
                        let _ := M.is_struct_tuple (| γ1_1, "core::option::Option::None" |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              A,
                              [],
                              "size_hint",
                              []
                            |),
                            [ M.read (| a |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let γ1_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "core::iter::adapters::chain::Chain",
                            "a"
                          |) in
                        let γ1_1 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "core::iter::adapters::chain::Chain",
                            "b"
                          |) in
                        let _ := M.is_struct_tuple (| γ1_0, "core::option::Option::None" |) in
                        let γ2_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ1_1,
                            "core::option::Option::Some",
                            0
                          |) in
                        let b := M.alloc (| γ2_0 |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              B,
                              [],
                              "size_hint",
                              []
                            |),
                            [ M.read (| b |) ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let γ1_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "core::iter::adapters::chain::Chain",
                            "a"
                          |) in
                        let γ1_1 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "core::iter::adapters::chain::Chain",
                            "b"
                          |) in
                        let _ := M.is_struct_tuple (| γ1_0, "core::option::Option::None" |) in
                        let _ := M.is_struct_tuple (| γ1_1, "core::option::Option::None" |) in
                        M.alloc (|
                          Value.Tuple
                            [
                              Value.Integer IntegerKind.Usize 0;
                              Value.StructTuple
                                "core::option::Option::Some"
                                [ Value.Integer IntegerKind.Usize 0 ]
                            ]
                        |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (A B : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::iterator::Iterator"
            (Self A B)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("Item", InstanceField.Ty (_Item A B));
              ("next", InstanceField.Method (next A B));
              ("count", InstanceField.Method (count A B));
              ("try_fold", InstanceField.Method (try_fold A B));
              ("fold", InstanceField.Method (fold A B));
              ("advance_by", InstanceField.Method (advance_by A B));
              ("nth", InstanceField.Method (nth A B));
              ("find", InstanceField.Method (find A B));
              ("last", InstanceField.Method (last A B));
              ("size_hint", InstanceField.Method (size_hint A B))
            ].
      End Impl_core_iter_traits_iterator_Iterator_where_core_iter_traits_iterator_Iterator_A_where_core_iter_traits_iterator_Iterator_B_for_core_iter_adapters_chain_Chain_A_B.
      
      Module Impl_core_iter_traits_double_ended_DoubleEndedIterator_where_core_iter_traits_double_ended_DoubleEndedIterator_A_where_core_iter_traits_double_ended_DoubleEndedIterator_B_for_core_iter_adapters_chain_Chain_A_B.
        Definition Self (A B : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::chain::Chain") [] [ A; B ].
        
        (*
            fn next_back(&mut self) -> Option<A::Item> {
                and_then_or_clear(&mut self.b, |b| b.next_back()).or_else(|| self.a.as_mut()?.next_back())
            }
        *)
        Definition next_back
            (A B : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ],
                  "or_else",
                  [
                    Ty.function
                      [ Ty.tuple [] ]
                      (Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ])
                  ]
                |),
                [
                  M.call_closure (|
                    M.get_function (|
                      "core::iter::adapters::chain::and_then_or_clear",
                      [
                        B;
                        Ty.associated;
                        Ty.function
                          [ Ty.tuple [ Ty.apply (Ty.path "&mut") [] [ B ] ] ]
                          (Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ])
                      ]
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::iter::adapters::chain::Chain",
                        "b"
                      |);
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let b := M.copy (| γ |) in
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::double_ended::DoubleEndedIterator",
                                            B,
                                            [],
                                            "next_back",
                                            []
                                          |),
                                          [ M.read (| b |) ]
                                        |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    ]
                  |);
                  M.closure
                    (fun γ =>
                      ltac:(M.monadic
                        match γ with
                        | [ α0 ] =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| α0 |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::double_ended::DoubleEndedIterator",
                                        A,
                                        [],
                                        "next_back",
                                        []
                                      |),
                                      [
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::try_trait::Try",
                                                  Ty.apply
                                                    (Ty.path "core::option::Option")
                                                    []
                                                    [ Ty.apply (Ty.path "&mut") [] [ A ] ],
                                                  [],
                                                  "branch",
                                                  []
                                                |),
                                                [
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "core::option::Option")
                                                        []
                                                        [ A ],
                                                      "as_mut",
                                                      []
                                                    |),
                                                    [
                                                      M.SubPointer.get_struct_record_field (|
                                                        M.read (| self |),
                                                        "core::iter::adapters::chain::Chain",
                                                        "a"
                                                      |)
                                                    ]
                                                  |)
                                                ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::ops::control_flow::ControlFlow::Break",
                                                      0
                                                    |) in
                                                  let residual := M.copy (| γ0_0 |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          M.call_closure (|
                                                            M.get_trait_method (|
                                                              "core::ops::try_trait::FromResidual",
                                                              Ty.apply
                                                                (Ty.path "core::option::Option")
                                                                []
                                                                [ Ty.associated ],
                                                              [
                                                                Ty.apply
                                                                  (Ty.path "core::option::Option")
                                                                  []
                                                                  [
                                                                    Ty.path
                                                                      "core::convert::Infallible"
                                                                  ]
                                                              ],
                                                              "from_residual",
                                                              []
                                                            |),
                                                            [ M.read (| residual |) ]
                                                          |)
                                                        |)
                                                      |)
                                                    |)
                                                  |)));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::ops::control_flow::ControlFlow::Continue",
                                                      0
                                                    |) in
                                                  let val := M.copy (| γ0_0 |) in
                                                  val))
                                            ]
                                          |)
                                        |)
                                      ]
                                    |)))
                              ]
                            |)))
                        | _ => M.impossible "wrong number of arguments"
                        end))
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn advance_back_by(&mut self, mut n: usize) -> Result<(), NonZero<usize>> {
                if let Some(ref mut b) = self.b {
                    n = match b.advance_back_by(n) {
                        Ok(()) => return Ok(()),
                        Err(k) => k.get(),
                    };
                    self.b = None;
                }
        
                if let Some(ref mut a) = self.a {
                    return a.advance_back_by(n);
                    // we don't fuse the second iterator
                }
        
                NonZero::new(n).map_or(Ok(()), Err)
            }
        *)
        Definition advance_back_by
            (A B : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self A B 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~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::chain::Chain",
                                  "b"
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let b := M.alloc (| γ0_0 |) in
                              let~ _ :=
                                M.write (|
                                  n,
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::double_ended::DoubleEndedIterator",
                                            B,
                                            [],
                                            "advance_back_by",
                                            []
                                          |),
                                          [ M.read (| b |); 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 k := 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 (| k |) ]
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                |) in
                              let~ _ :=
                                M.write (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::chain::Chain",
                                    "b"
                                  |),
                                  Value.StructTuple "core::option::Option::None" []
                                |) in
                              M.alloc (| Value.Tuple [] |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    let~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::chain::Chain",
                                  "a"
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let a := M.alloc (| γ0_0 |) in
                              M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    M.return_ (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::iter::traits::double_ended::DoubleEndedIterator",
                                          A,
                                          [],
                                          "advance_back_by",
                                          []
                                        |),
                                        [ M.read (| a |); M.read (| n |) ]
                                      |)
                                    |)
                                  |)
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (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.
        
        (*
            fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
                if let Some(ref mut b) = self.b {
                    n = match b.advance_back_by(n) {
                        Ok(()) => match b.next_back() {
                            None => 0,
                            x => return x,
                        },
                        Err(k) => k.get(),
                    };
        
                    self.b = None;
                }
        
                self.a.as_mut()?.nth_back(n)
            }
        *)
        Definition nth_back
            (A B : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self A B 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~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::chain::Chain",
                                  "b"
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let b := M.alloc (| γ0_0 |) in
                              let~ _ :=
                                M.write (|
                                  n,
                                  M.read (|
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::double_ended::DoubleEndedIterator",
                                            B,
                                            [],
                                            "advance_back_by",
                                            []
                                          |),
                                          [ M.read (| b |); M.read (| n |) ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::result::Result::Ok",
                                                0
                                              |) in
                                            M.match_operator (|
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::iter::traits::double_ended::DoubleEndedIterator",
                                                    B,
                                                    [],
                                                    "next_back",
                                                    []
                                                  |),
                                                  [ M.read (| b |) ]
                                                |)
                                              |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let _ :=
                                                      M.is_struct_tuple (|
                                                        γ,
                                                        "core::option::Option::None"
                                                      |) in
                                                    M.alloc (|
                                                      Value.Integer IntegerKind.Usize 0
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let x := M.copy (| γ |) in
                                                    M.alloc (|
                                                      M.never_to_any (|
                                                        M.read (| M.return_ (| M.read (| x |) |) |)
                                                      |)
                                                    |)))
                                              ]
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::result::Result::Err",
                                                0
                                              |) in
                                            let k := 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 (| k |) ]
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                |) in
                              let~ _ :=
                                M.write (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "core::iter::adapters::chain::Chain",
                                    "b"
                                  |),
                                  Value.StructTuple "core::option::Option::None" []
                                |) in
                              M.alloc (| Value.Tuple [] |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::double_ended::DoubleEndedIterator",
                          A,
                          [],
                          "nth_back",
                          []
                        |),
                        [
                          M.read (|
                            M.match_operator (|
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::ops::try_trait::Try",
                                    Ty.apply
                                      (Ty.path "core::option::Option")
                                      []
                                      [ Ty.apply (Ty.path "&mut") [] [ A ] ],
                                    [],
                                    "branch",
                                    []
                                  |),
                                  [
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "core::option::Option") [] [ A ],
                                        "as_mut",
                                        []
                                      |),
                                      [
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::iter::adapters::chain::Chain",
                                          "a"
                                        |)
                                      ]
                                    |)
                                  ]
                                |)
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::ops::control_flow::ControlFlow::Break",
                                        0
                                      |) in
                                    let residual := M.copy (| γ0_0 |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::ops::try_trait::FromResidual",
                                                Ty.apply
                                                  (Ty.path "core::option::Option")
                                                  []
                                                  [ Ty.associated ],
                                                [
                                                  Ty.apply
                                                    (Ty.path "core::option::Option")
                                                    []
                                                    [ Ty.path "core::convert::Infallible" ]
                                                ],
                                                "from_residual",
                                                []
                                              |),
                                              [ M.read (| residual |) ]
                                            |)
                                          |)
                                        |)
                                      |)
                                    |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::ops::control_flow::ControlFlow::Continue",
                                        0
                                      |) in
                                    let val := M.copy (| γ0_0 |) in
                                    val))
                              ]
                            |)
                          |);
                          M.read (| n |)
                        ]
                      |)
                    |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
            where
                P: FnMut(&Self::Item) -> bool,
            {
                and_then_or_clear(&mut self.b, |b| b.rfind(&mut predicate))
                    .or_else(|| self.a.as_mut()?.rfind(predicate))
            }
        *)
        Definition rfind (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [ P ], [ self; predicate ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let predicate := M.alloc (| predicate |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ],
                  "or_else",
                  [
                    Ty.function
                      [ Ty.tuple [] ]
                      (Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ])
                  ]
                |),
                [
                  M.call_closure (|
                    M.get_function (|
                      "core::iter::adapters::chain::and_then_or_clear",
                      [
                        B;
                        Ty.associated;
                        Ty.function
                          [ Ty.tuple [ Ty.apply (Ty.path "&mut") [] [ B ] ] ]
                          (Ty.apply (Ty.path "core::option::Option") [] [ Ty.associated ])
                      ]
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::iter::adapters::chain::Chain",
                        "b"
                      |);
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let b := M.copy (| γ |) in
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::double_ended::DoubleEndedIterator",
                                            B,
                                            [],
                                            "rfind",
                                            [ Ty.apply (Ty.path "&mut") [] [ P ] ]
                                          |),
                                          [ M.read (| b |); predicate ]
                                        |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    ]
                  |);
                  M.closure
                    (fun γ =>
                      ltac:(M.monadic
                        match γ with
                        | [ α0 ] =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| α0 |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::double_ended::DoubleEndedIterator",
                                        A,
                                        [],
                                        "rfind",
                                        [ P ]
                                      |),
                                      [
                                        M.read (|
                                          M.match_operator (|
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::try_trait::Try",
                                                  Ty.apply
                                                    (Ty.path "core::option::Option")
                                                    []
                                                    [ Ty.apply (Ty.path "&mut") [] [ A ] ],
                                                  [],
                                                  "branch",
                                                  []
                                                |),
                                                [
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "core::option::Option")
                                                        []
                                                        [ A ],
                                                      "as_mut",
                                                      []
                                                    |),
                                                    [
                                                      M.SubPointer.get_struct_record_field (|
                                                        M.read (| self |),
                                                        "core::iter::adapters::chain::Chain",
                                                        "a"
                                                      |)
                                                    ]
                                                  |)
                                                ]
                                              |)
                                            |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::ops::control_flow::ControlFlow::Break",
                                                      0
                                                    |) in
                                                  let residual := M.copy (| γ0_0 |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        M.return_ (|
                                                          M.call_closure (|
                                                            M.get_trait_method (|
                                                              "core::ops::try_trait::FromResidual",
                                                              Ty.apply
                                                                (Ty.path "core::option::Option")
                                                                []
                                                                [ Ty.associated ],
                                                              [
                                                                Ty.apply
                                                                  (Ty.path "core::option::Option")
                                                                  []
                                                                  [
                                                                    Ty.path
                                                                      "core::convert::Infallible"
                                                                  ]
                                                              ],
                                                              "from_residual",
                                                              []
                                                            |),
                                                            [ M.read (| residual |) ]
                                                          |)
                                                        |)
                                                      |)
                                                    |)
                                                  |)));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::ops::control_flow::ControlFlow::Continue",
                                                      0
                                                    |) in
                                                  let val := M.copy (| γ0_0 |) in
                                                  val))
                                            ]
                                          |)
                                        |);
                                        M.read (| predicate |)
                                      ]
                                    |)))
                              ]
                            |)))
                        | _ => M.impossible "wrong number of arguments"
                        end))
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn try_rfold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
            where
                Self: Sized,
                F: FnMut(Acc, Self::Item) -> R,
                R: Try<Output = Acc>,
            {
                if let Some(ref mut b) = self.b {
                    acc = b.try_rfold(acc, &mut f)?;
                    self.b = None;
                }
                if let Some(ref mut a) = self.a {
                    acc = a.try_rfold(acc, f)?;
                    // we don't fuse the second iterator
                }
                try { acc }
            }
        *)
        Definition try_rfold
            (A B : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self A B 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.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::chain::Chain",
                                  "b"
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let b := M.alloc (| γ0_0 |) 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::double_ended::DoubleEndedIterator",
                                                B,
                                                [],
                                                "try_rfold",
                                                [ Acc; Ty.apply (Ty.path "&mut") [] [ F ]; R ]
                                              |),
                                              [ M.read (| b |); 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::chain::Chain",
                                    "b"
                                  |),
                                  Value.StructTuple "core::option::Option::None" []
                                |) in
                              M.alloc (| Value.Tuple [] |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    let~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::iter::adapters::chain::Chain",
                                  "a"
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let a := M.alloc (| γ0_0 |) 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::double_ended::DoubleEndedIterator",
                                                A,
                                                [],
                                                "try_rfold",
                                                [ Acc; F; R ]
                                              |),
                                              [ M.read (| a |); M.read (| acc |); M.read (| 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 [] |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::ops::try_trait::Try",
                          R,
                          [],
                          "from_output",
                          []
                        |),
                        [ M.read (| acc |) ]
                      |)
                    |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn rfold<Acc, F>(self, mut acc: Acc, mut f: F) -> Acc
            where
                F: FnMut(Acc, Self::Item) -> Acc,
            {
                if let Some(b) = self.b {
                    acc = b.rfold(acc, &mut f);
                }
                if let Some(a) = self.a {
                    acc = a.rfold(acc, f);
                }
                acc
            }
        *)
        Definition rfold (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [ Acc; F ], [ 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.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.SubPointer.get_struct_record_field (|
                              self,
                              "core::iter::adapters::chain::Chain",
                              "b"
                            |) in
                          let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let b := M.copy (| γ0_0 |) in
                          let~ _ :=
                            M.write (|
                              acc,
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::double_ended::DoubleEndedIterator",
                                  B,
                                  [],
                                  "rfold",
                                  [ Acc; Ty.apply (Ty.path "&mut") [] [ F ] ]
                                |),
                                [ M.read (| b |); M.read (| acc |); f ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.SubPointer.get_struct_record_field (|
                              self,
                              "core::iter::adapters::chain::Chain",
                              "a"
                            |) in
                          let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let a := M.copy (| γ0_0 |) in
                          let~ _ :=
                            M.write (|
                              acc,
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::double_ended::DoubleEndedIterator",
                                  A,
                                  [],
                                  "rfold",
                                  [ Acc; F ]
                                |),
                                [ M.read (| a |); M.read (| acc |); M.read (| f |) ]
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                acc
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (A B : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::double_ended::DoubleEndedIterator"
            (Self A B)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("next_back", InstanceField.Method (next_back A B));
              ("advance_back_by", InstanceField.Method (advance_back_by A B));
              ("nth_back", InstanceField.Method (nth_back A B));
              ("rfind", InstanceField.Method (rfind A B));
              ("try_rfold", InstanceField.Method (try_rfold A B));
              ("rfold", InstanceField.Method (rfold A B))
            ].
      End Impl_core_iter_traits_double_ended_DoubleEndedIterator_where_core_iter_traits_double_ended_DoubleEndedIterator_A_where_core_iter_traits_double_ended_DoubleEndedIterator_B_for_core_iter_adapters_chain_Chain_A_B.
      
      Module Impl_core_iter_traits_marker_FusedIterator_where_core_iter_traits_marker_FusedIterator_A_where_core_iter_traits_marker_FusedIterator_B_for_core_iter_adapters_chain_Chain_A_B.
        Definition Self (A B : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::chain::Chain") [] [ A; B ].
        
        Axiom Implements :
          forall (A B : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::marker::FusedIterator"
            (Self A B)
            (* Trait polymorphic types *) []
            (* Instance *) [].
      End Impl_core_iter_traits_marker_FusedIterator_where_core_iter_traits_marker_FusedIterator_A_where_core_iter_traits_marker_FusedIterator_B_for_core_iter_adapters_chain_Chain_A_B.
      
      Module Impl_core_iter_traits_marker_TrustedLen_where_core_iter_traits_marker_TrustedLen_A_where_core_iter_traits_marker_TrustedLen_B_for_core_iter_adapters_chain_Chain_A_B.
        Definition Self (A B : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::chain::Chain") [] [ A; B ].
        
        Axiom Implements :
          forall (A B : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::marker::TrustedLen"
            (Self A B)
            (* Trait polymorphic types *) []
            (* Instance *) [].
      End Impl_core_iter_traits_marker_TrustedLen_where_core_iter_traits_marker_TrustedLen_A_where_core_iter_traits_marker_TrustedLen_B_for_core_iter_adapters_chain_Chain_A_B.
      
      Module Impl_core_default_Default_where_core_default_Default_A_where_core_default_Default_B_for_core_iter_adapters_chain_Chain_A_B.
        Definition Self (A B : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::chain::Chain") [] [ A; B ].
        
        (*
            fn default() -> Self {
                Chain::new(Default::default(), Default::default())
            }
        *)
        Definition default (A B : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self A B in
          match ε, τ, α with
          | [], [], [] =>
            ltac:(M.monadic
              (M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::iter::adapters::chain::Chain") [] [ A; B ],
                  "new",
                  []
                |),
                [
                  M.call_closure (|
                    M.get_trait_method (| "core::default::Default", A, [], "default", [] |),
                    []
                  |);
                  M.call_closure (|
                    M.get_trait_method (| "core::default::Default", B, [], "default", [] |),
                    []
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (A B : Ty.t),
          M.IsTraitInstance
            "core::default::Default"
            (Self A B)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("default", InstanceField.Method (default A B)) ].
      End Impl_core_default_Default_where_core_default_Default_A_where_core_default_Default_B_for_core_iter_adapters_chain_Chain_A_B.
      
      (*
      fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
          let x = f(opt.as_mut()?);
          if x.is_none() {
              *opt = None;
          }
          x
      }
      *)
      Definition and_then_or_clear (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ T; U; impl_FnOnce__mut_T__arrow_Option_U_ ], [ opt; f ] =>
          ltac:(M.monadic
            (let opt := M.alloc (| opt |) in
            let f := M.alloc (| f |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ x :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::ops::function::FnOnce",
                          impl_FnOnce__mut_T__arrow_Option_U_,
                          [ Ty.tuple [ Ty.apply (Ty.path "&mut") [] [ T ] ] ],
                          "call_once",
                          []
                        |),
                        [
                          M.read (| f |);
                          Value.Tuple
                            [
                              M.read (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::Try",
                                        Ty.apply
                                          (Ty.path "core::option::Option")
                                          []
                                          [ Ty.apply (Ty.path "&mut") [] [ T ] ],
                                        [],
                                        "branch",
                                        []
                                      |),
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.apply (Ty.path "core::option::Option") [] [ T ],
                                            "as_mut",
                                            []
                                          |),
                                          [ M.read (| opt |) ]
                                        |)
                                      ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::ops::control_flow::ControlFlow::Break",
                                            0
                                          |) in
                                        let residual := M.copy (| γ0_0 |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::ops::try_trait::FromResidual",
                                                    Ty.apply
                                                      (Ty.path "core::option::Option")
                                                      []
                                                      [ U ],
                                                    [
                                                      Ty.apply
                                                        (Ty.path "core::option::Option")
                                                        []
                                                        [ Ty.path "core::convert::Infallible" ]
                                                    ],
                                                    "from_residual",
                                                    []
                                                  |),
                                                  [ M.read (| residual |) ]
                                                |)
                                              |)
                                            |)
                                          |)
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::ops::control_flow::ControlFlow::Continue",
                                            0
                                          |) in
                                        let val := M.copy (| γ0_0 |) in
                                        M.alloc (| M.read (| val |) |)))
                                  ]
                                |)
                              |)
                            ]
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "core::option::Option") [] [ U ],
                                      "is_none",
                                      []
                                    |),
                                    [ x ]
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            let~ _ :=
                              M.write (|
                                M.read (| opt |),
                                Value.StructTuple "core::option::Option::None" []
                              |) in
                            M.alloc (| Value.Tuple [] |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  x
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Function_and_then_or_clear :
        M.IsFunction "core::iter::adapters::chain::and_then_or_clear" and_then_or_clear.
    End chain.
  End adapters.
End iter.
