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

Module str.
  Module pattern.
    (* Trait *)
    Module Pattern.
      Definition is_contained_in
          (Self : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply
                  (Ty.path "core::option::Option")
                  []
                  [ Ty.tuple [ Ty.path "usize"; Ty.path "usize" ] ],
                "is_some",
                []
              |),
              [
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::str::pattern::Searcher",
                      Ty.associated,
                      [],
                      "next_match",
                      []
                    |),
                    [
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::str::pattern::Pattern",
                            Self,
                            [],
                            "into_searcher",
                            []
                          |),
                          [ M.read (| self |); M.read (| haystack |) ]
                        |)
                      |)
                    ]
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom ProvidedMethod_is_contained_in :
        M.IsProvidedMethod "core::str::pattern::Pattern" "is_contained_in" is_contained_in.
      Definition is_prefix_of
          (Self : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.read (|
              M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::str::pattern::Searcher",
                      Ty.associated,
                      [],
                      "next",
                      []
                    |),
                    [
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::str::pattern::Pattern",
                            Self,
                            [],
                            "into_searcher",
                            []
                          |),
                          [ M.read (| self |); M.read (| haystack |) ]
                        |)
                      |)
                    ]
                  |)
                |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Match",
                          0
                        |) in
                      let γ0_1 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Match",
                          1
                        |) in
                      let _ :=
                        M.is_constant_or_break_match (|
                          M.read (| γ0_0 |),
                          Value.Integer IntegerKind.Usize 0
                        |) in
                      M.alloc (| Value.Bool true |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom ProvidedMethod_is_prefix_of :
        M.IsProvidedMethod "core::str::pattern::Pattern" "is_prefix_of" is_prefix_of.
      Definition is_suffix_of
          (Self : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.read (|
              M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::str::pattern::ReverseSearcher",
                      Ty.associated,
                      [],
                      "next_back",
                      []
                    |),
                    [
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::str::pattern::Pattern",
                            Self,
                            [],
                            "into_searcher",
                            []
                          |),
                          [ M.read (| self |); M.read (| haystack |) ]
                        |)
                      |)
                    ]
                  |)
                |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Match",
                          0
                        |) in
                      let γ0_1 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Match",
                          1
                        |) in
                      let j := M.copy (| γ0_1 |) in
                      let γ :=
                        M.alloc (|
                          BinOp.eq (|
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "len", [] |),
                              [ M.read (| haystack |) ]
                            |),
                            M.read (| j |)
                          |)
                        |) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      M.alloc (| Value.Bool true |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom ProvidedMethod_is_suffix_of :
        M.IsProvidedMethod "core::str::pattern::Pattern" "is_suffix_of" is_suffix_of.
      Definition strip_prefix_of
          (Self : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.read (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::str::pattern::Searcher",
                              Ty.associated,
                              [],
                              "next",
                              []
                            |),
                            [
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::str::pattern::Pattern",
                                    Self,
                                    [],
                                    "into_searcher",
                                    []
                                  |),
                                  [ M.read (| self |); M.read (| haystack |) ]
                                |)
                              |)
                            ]
                          |)
                        |) in
                      let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Match",
                          0
                        |) in
                      let γ0_1 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Match",
                          1
                        |) in
                      let start := M.copy (| γ0_0 |) in
                      let len := M.copy (| γ0_1 |) in
                      let~ _ :=
                        M.match_operator (|
                          M.alloc (| Value.Tuple [] |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ := M.use (M.alloc (| Value.Bool true |)) in
                                let _ :=
                                  M.is_constant_or_break_match (|
                                    M.read (| γ |),
                                    Value.Bool true
                                  |) in
                                let~ _ :=
                                  M.match_operator (|
                                    M.alloc (|
                                      Value.Tuple
                                        [ start; M.alloc (| Value.Integer IntegerKind.Usize 0 |) ]
                                    |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                          let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                          let left_val := M.copy (| γ0_0 |) in
                                          let right_val := M.copy (| γ0_1 |) in
                                          M.match_operator (|
                                            M.alloc (| Value.Tuple [] |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ :=
                                                    M.use
                                                      (M.alloc (|
                                                        UnOp.not (|
                                                          BinOp.eq (|
                                                            M.read (| M.read (| left_val |) |),
                                                            M.read (| M.read (| right_val |) |)
                                                          |)
                                                        |)
                                                      |)) in
                                                  let _ :=
                                                    M.is_constant_or_break_match (|
                                                      M.read (| γ |),
                                                      Value.Bool true
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        let~ kind :=
                                                          M.alloc (|
                                                            Value.StructTuple
                                                              "core::panicking::AssertKind::Eq"
                                                              []
                                                          |) in
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_function (|
                                                              "core::panicking::assert_failed",
                                                              [ Ty.path "usize"; Ty.path "usize" ]
                                                            |),
                                                            [
                                                              M.read (| kind |);
                                                              M.read (| left_val |);
                                                              M.read (| right_val |);
                                                              Value.StructTuple
                                                                "core::option::Option::Some"
                                                                [
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path
                                                                        "core::fmt::Arguments",
                                                                      "new_const",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.alloc (|
                                                                        Value.Array
                                                                          [
                                                                            M.read (|
                                                                              Value.String
                                                                                "The first search step from Searcher must include the first character"
                                                                            |)
                                                                          ]
                                                                      |)
                                                                    ]
                                                                  |)
                                                                ]
                                                            ]
                                                          |)
                                                        |)
                                                      |)
                                                    |)
                                                  |)));
                                              fun γ =>
                                                ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                            ]
                                          |)))
                                    ]
                                  |) in
                                M.alloc (| Value.Tuple [] |)));
                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                          ]
                        |) in
                      M.alloc (|
                        Value.StructTuple
                          "core::option::Option::Some"
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "str",
                                "get_unchecked",
                                [
                                  Ty.apply
                                    (Ty.path "core::ops::range::RangeFrom")
                                    []
                                    [ Ty.path "usize" ]
                                ]
                              |),
                              [
                                M.read (| haystack |);
                                Value.StructRecord
                                  "core::ops::range::RangeFrom"
                                  [ ("start", M.read (| len |)) ]
                              ]
                            |)
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom ProvidedMethod_strip_prefix_of :
        M.IsProvidedMethod "core::str::pattern::Pattern" "strip_prefix_of" strip_prefix_of.
      Definition strip_suffix_of
          (Self : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.read (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::str::pattern::ReverseSearcher",
                              Ty.associated,
                              [],
                              "next_back",
                              []
                            |),
                            [
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::str::pattern::Pattern",
                                    Self,
                                    [],
                                    "into_searcher",
                                    []
                                  |),
                                  [ M.read (| self |); M.read (| haystack |) ]
                                |)
                              |)
                            ]
                          |)
                        |) in
                      let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Match",
                          0
                        |) in
                      let γ0_1 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Match",
                          1
                        |) in
                      let start := M.copy (| γ0_0 |) in
                      let end_ := M.copy (| γ0_1 |) in
                      let~ _ :=
                        M.match_operator (|
                          M.alloc (| Value.Tuple [] |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ := M.use (M.alloc (| Value.Bool true |)) in
                                let _ :=
                                  M.is_constant_or_break_match (|
                                    M.read (| γ |),
                                    Value.Bool true
                                  |) in
                                let~ _ :=
                                  M.match_operator (|
                                    M.alloc (|
                                      Value.Tuple
                                        [
                                          end_;
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "str",
                                                "len",
                                                []
                                              |),
                                              [ M.read (| haystack |) ]
                                            |)
                                          |)
                                        ]
                                    |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                          let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                          let left_val := M.copy (| γ0_0 |) in
                                          let right_val := M.copy (| γ0_1 |) in
                                          M.match_operator (|
                                            M.alloc (| Value.Tuple [] |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ :=
                                                    M.use
                                                      (M.alloc (|
                                                        UnOp.not (|
                                                          BinOp.eq (|
                                                            M.read (| M.read (| left_val |) |),
                                                            M.read (| M.read (| right_val |) |)
                                                          |)
                                                        |)
                                                      |)) in
                                                  let _ :=
                                                    M.is_constant_or_break_match (|
                                                      M.read (| γ |),
                                                      Value.Bool true
                                                    |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        let~ kind :=
                                                          M.alloc (|
                                                            Value.StructTuple
                                                              "core::panicking::AssertKind::Eq"
                                                              []
                                                          |) in
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_function (|
                                                              "core::panicking::assert_failed",
                                                              [ Ty.path "usize"; Ty.path "usize" ]
                                                            |),
                                                            [
                                                              M.read (| kind |);
                                                              M.read (| left_val |);
                                                              M.read (| right_val |);
                                                              Value.StructTuple
                                                                "core::option::Option::Some"
                                                                [
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path
                                                                        "core::fmt::Arguments",
                                                                      "new_const",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.alloc (|
                                                                        Value.Array
                                                                          [
                                                                            M.read (|
                                                                              Value.String
                                                                                "The first search step from ReverseSearcher must include the last character"
                                                                            |)
                                                                          ]
                                                                      |)
                                                                    ]
                                                                  |)
                                                                ]
                                                            ]
                                                          |)
                                                        |)
                                                      |)
                                                    |)
                                                  |)));
                                              fun γ =>
                                                ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                            ]
                                          |)))
                                    ]
                                  |) in
                                M.alloc (| Value.Tuple [] |)));
                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                          ]
                        |) in
                      M.alloc (|
                        Value.StructTuple
                          "core::option::Option::Some"
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "str",
                                "get_unchecked",
                                [
                                  Ty.apply
                                    (Ty.path "core::ops::range::RangeTo")
                                    []
                                    [ Ty.path "usize" ]
                                ]
                              |),
                              [
                                M.read (| haystack |);
                                Value.StructRecord
                                  "core::ops::range::RangeTo"
                                  [ ("end_", M.read (| start |)) ]
                              ]
                            |)
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom ProvidedMethod_strip_suffix_of :
        M.IsProvidedMethod "core::str::pattern::Pattern" "strip_suffix_of" strip_suffix_of.
    End Pattern.
    
    (*
    Enum SearchStep
    {
      const_params := [];
      ty_params := [];
      variants :=
        [
          {
            name := "Match";
            item := StructTuple [ Ty.path "usize"; Ty.path "usize" ];
            discriminant := None;
          };
          {
            name := "Reject";
            item := StructTuple [ Ty.path "usize"; Ty.path "usize" ];
            discriminant := None;
          };
          {
            name := "Done";
            item := StructTuple [];
            discriminant := None;
          }
        ];
    }
    *)
    
    Module Impl_core_marker_Copy_for_core_str_pattern_SearchStep.
      Definition Self : Ty.t := Ty.path "core::str::pattern::SearchStep".
      
      Axiom Implements :
        M.IsTraitInstance
          "core::marker::Copy"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_Copy_for_core_str_pattern_SearchStep.
    
    Module Impl_core_clone_Clone_for_core_str_pattern_SearchStep.
      Definition Self : Ty.t := Ty.path "core::str::pattern::SearchStep".
      
      (* Clone *)
      Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                Value.DeclaredButUndefined,
                [ fun γ => ltac:(M.monadic (M.read (| self |))) ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::clone::Clone"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method clone) ].
    End Impl_core_clone_Clone_for_core_str_pattern_SearchStep.
    
    Module Impl_core_cmp_Eq_for_core_str_pattern_SearchStep.
      Definition Self : Ty.t := Ty.path "core::str::pattern::SearchStep".
      
      (* Eq *)
      Definition assert_receiver_is_total_eq
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                Value.DeclaredButUndefined,
                [ fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |))) ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::cmp::Eq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [ ("assert_receiver_is_total_eq", InstanceField.Method assert_receiver_is_total_eq) ].
    End Impl_core_cmp_Eq_for_core_str_pattern_SearchStep.
    
    Module Impl_core_marker_StructuralPartialEq_for_core_str_pattern_SearchStep.
      Definition Self : Ty.t := Ty.path "core::str::pattern::SearchStep".
      
      Axiom Implements :
        M.IsTraitInstance
          "core::marker::StructuralPartialEq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_StructuralPartialEq_for_core_str_pattern_SearchStep.
    
    Module Impl_core_cmp_PartialEq_for_core_str_pattern_SearchStep.
      Definition Self : Ty.t := Ty.path "core::str::pattern::SearchStep".
      
      (* PartialEq *)
      Definition eq (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; other ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let other := M.alloc (| other |) in
            M.read (|
              let~ __self_discr :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (|
                      "core::intrinsics::discriminant_value",
                      [ Ty.path "core::str::pattern::SearchStep" ]
                    |),
                    [ M.read (| self |) ]
                  |)
                |) in
              let~ __arg1_discr :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (|
                      "core::intrinsics::discriminant_value",
                      [ Ty.path "core::str::pattern::SearchStep" ]
                    |),
                    [ M.read (| other |) ]
                  |)
                |) in
              M.alloc (|
                LogicalOp.and (|
                  BinOp.eq (| M.read (| __self_discr |), M.read (| __arg1_discr |) |),
                  ltac:(M.monadic
                    (M.read (|
                      M.match_operator (|
                        M.alloc (| Value.Tuple [ M.read (| self |); M.read (| other |) ] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                              let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                              let γ0_0 := M.read (| γ0_0 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "core::str::pattern::SearchStep::Match",
                                  0
                                |) in
                              let γ2_1 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "core::str::pattern::SearchStep::Match",
                                  1
                                |) in
                              let __self_0 := M.alloc (| γ2_0 |) in
                              let __self_1 := M.alloc (| γ2_1 |) in
                              let γ0_1 := M.read (| γ0_1 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "core::str::pattern::SearchStep::Match",
                                  0
                                |) in
                              let γ2_1 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "core::str::pattern::SearchStep::Match",
                                  1
                                |) in
                              let __arg1_0 := M.alloc (| γ2_0 |) in
                              let __arg1_1 := M.alloc (| γ2_1 |) in
                              M.alloc (|
                                LogicalOp.and (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::cmp::PartialEq",
                                      Ty.apply (Ty.path "&") [] [ Ty.path "usize" ],
                                      [ Ty.apply (Ty.path "&") [] [ Ty.path "usize" ] ],
                                      "eq",
                                      []
                                    |),
                                    [ __self_0; __arg1_0 ]
                                  |),
                                  ltac:(M.monadic
                                    (M.call_closure (|
                                      M.get_trait_method (|
                                        "core::cmp::PartialEq",
                                        Ty.apply (Ty.path "&") [] [ Ty.path "usize" ],
                                        [ Ty.apply (Ty.path "&") [] [ Ty.path "usize" ] ],
                                        "eq",
                                        []
                                      |),
                                      [ __self_1; __arg1_1 ]
                                    |)))
                                |)
                              |)));
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                              let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                              let γ0_0 := M.read (| γ0_0 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "core::str::pattern::SearchStep::Reject",
                                  0
                                |) in
                              let γ2_1 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "core::str::pattern::SearchStep::Reject",
                                  1
                                |) in
                              let __self_0 := M.alloc (| γ2_0 |) in
                              let __self_1 := M.alloc (| γ2_1 |) in
                              let γ0_1 := M.read (| γ0_1 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "core::str::pattern::SearchStep::Reject",
                                  0
                                |) in
                              let γ2_1 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "core::str::pattern::SearchStep::Reject",
                                  1
                                |) in
                              let __arg1_0 := M.alloc (| γ2_0 |) in
                              let __arg1_1 := M.alloc (| γ2_1 |) in
                              M.alloc (|
                                LogicalOp.and (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::cmp::PartialEq",
                                      Ty.apply (Ty.path "&") [] [ Ty.path "usize" ],
                                      [ Ty.apply (Ty.path "&") [] [ Ty.path "usize" ] ],
                                      "eq",
                                      []
                                    |),
                                    [ __self_0; __arg1_0 ]
                                  |),
                                  ltac:(M.monadic
                                    (M.call_closure (|
                                      M.get_trait_method (|
                                        "core::cmp::PartialEq",
                                        Ty.apply (Ty.path "&") [] [ Ty.path "usize" ],
                                        [ Ty.apply (Ty.path "&") [] [ Ty.path "usize" ] ],
                                        "eq",
                                        []
                                      |),
                                      [ __self_1; __arg1_1 ]
                                    |)))
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)))
                        ]
                      |)
                    |)))
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::cmp::PartialEq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("eq", InstanceField.Method eq) ].
    End Impl_core_cmp_PartialEq_for_core_str_pattern_SearchStep.
    
    Module Impl_core_fmt_Debug_for_core_str_pattern_SearchStep.
      Definition Self : Ty.t := Ty.path "core::str::pattern::SearchStep".
      
      (* Debug *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.read (|
              M.match_operator (|
                self,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Match",
                          0
                        |) in
                      let γ1_1 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Match",
                          1
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      let __self_1 := M.alloc (| γ1_1 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "debug_tuple_field2_finish",
                            []
                          |),
                          [
                            M.read (| f |);
                            M.read (| Value.String "Match" |);
                            M.read (| __self_0 |);
                            __self_1
                          ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Reject",
                          0
                        |) in
                      let γ1_1 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::SearchStep::Reject",
                          1
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      let __self_1 := M.alloc (| γ1_1 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "debug_tuple_field2_finish",
                            []
                          |),
                          [
                            M.read (| f |);
                            M.read (| Value.String "Reject" |);
                            M.read (| __self_0 |);
                            __self_1
                          ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let _ := M.is_struct_tuple (| γ, "core::str::pattern::SearchStep::Done" |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "write_str",
                            []
                          |),
                          [ M.read (| f |); M.read (| Value.String "Done" |) ]
                        |)
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Debug"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Debug_for_core_str_pattern_SearchStep.
    
    (* Trait *)
    Module Searcher.
      Definition next_match
          (Self : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.never_to_any (|
                  M.read (|
                    M.loop (|
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::str::pattern::Searcher",
                                Self,
                                [],
                                "next",
                                []
                              |),
                              [ M.read (| self |) ]
                            |)
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::str::pattern::SearchStep::Match",
                                    0
                                  |) in
                                let γ0_1 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::str::pattern::SearchStep::Match",
                                    1
                                  |) in
                                let a := M.copy (| γ0_0 |) in
                                let b := M.copy (| γ0_1 |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.read (|
                                      M.return_ (|
                                        Value.StructTuple
                                          "core::option::Option::Some"
                                          [ Value.Tuple [ M.read (| a |); M.read (| b |) ] ]
                                      |)
                                    |)
                                  |)
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (let _ :=
                                  M.is_struct_tuple (|
                                    γ,
                                    "core::str::pattern::SearchStep::Done"
                                  |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.read (|
                                      M.return_ (|
                                        Value.StructTuple "core::option::Option::None" []
                                      |)
                                    |)
                                  |)
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (M.alloc (| M.never_to_any (| M.read (| M.continue (||) |) |) |)))
                          ]
                        |)))
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom ProvidedMethod_next_match :
        M.IsProvidedMethod "core::str::pattern::Searcher" "next_match" next_match.
      Definition next_reject
          (Self : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.never_to_any (|
                  M.read (|
                    M.loop (|
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::str::pattern::Searcher",
                                Self,
                                [],
                                "next",
                                []
                              |),
                              [ M.read (| self |) ]
                            |)
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::str::pattern::SearchStep::Reject",
                                    0
                                  |) in
                                let γ0_1 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::str::pattern::SearchStep::Reject",
                                    1
                                  |) in
                                let a := M.copy (| γ0_0 |) in
                                let b := M.copy (| γ0_1 |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.read (|
                                      M.return_ (|
                                        Value.StructTuple
                                          "core::option::Option::Some"
                                          [ Value.Tuple [ M.read (| a |); M.read (| b |) ] ]
                                      |)
                                    |)
                                  |)
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (let _ :=
                                  M.is_struct_tuple (|
                                    γ,
                                    "core::str::pattern::SearchStep::Done"
                                  |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.read (|
                                      M.return_ (|
                                        Value.StructTuple "core::option::Option::None" []
                                      |)
                                    |)
                                  |)
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (M.alloc (| M.never_to_any (| M.read (| M.continue (||) |) |) |)))
                          ]
                        |)))
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom ProvidedMethod_next_reject :
        M.IsProvidedMethod "core::str::pattern::Searcher" "next_reject" next_reject.
    End Searcher.
    
    (* Trait *)
    Module ReverseSearcher.
      Definition next_match_back
          (Self : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.never_to_any (|
                  M.read (|
                    M.loop (|
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::str::pattern::ReverseSearcher",
                                Self,
                                [],
                                "next_back",
                                []
                              |),
                              [ M.read (| self |) ]
                            |)
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::str::pattern::SearchStep::Match",
                                    0
                                  |) in
                                let γ0_1 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::str::pattern::SearchStep::Match",
                                    1
                                  |) in
                                let a := M.copy (| γ0_0 |) in
                                let b := M.copy (| γ0_1 |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.read (|
                                      M.return_ (|
                                        Value.StructTuple
                                          "core::option::Option::Some"
                                          [ Value.Tuple [ M.read (| a |); M.read (| b |) ] ]
                                      |)
                                    |)
                                  |)
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (let _ :=
                                  M.is_struct_tuple (|
                                    γ,
                                    "core::str::pattern::SearchStep::Done"
                                  |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.read (|
                                      M.return_ (|
                                        Value.StructTuple "core::option::Option::None" []
                                      |)
                                    |)
                                  |)
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (M.alloc (| M.never_to_any (| M.read (| M.continue (||) |) |) |)))
                          ]
                        |)))
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom ProvidedMethod_next_match_back :
        M.IsProvidedMethod "core::str::pattern::ReverseSearcher" "next_match_back" next_match_back.
      Definition next_reject_back
          (Self : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.never_to_any (|
                  M.read (|
                    M.loop (|
                      ltac:(M.monadic
                        (M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::str::pattern::ReverseSearcher",
                                Self,
                                [],
                                "next_back",
                                []
                              |),
                              [ M.read (| self |) ]
                            |)
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::str::pattern::SearchStep::Reject",
                                    0
                                  |) in
                                let γ0_1 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::str::pattern::SearchStep::Reject",
                                    1
                                  |) in
                                let a := M.copy (| γ0_0 |) in
                                let b := M.copy (| γ0_1 |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.read (|
                                      M.return_ (|
                                        Value.StructTuple
                                          "core::option::Option::Some"
                                          [ Value.Tuple [ M.read (| a |); M.read (| b |) ] ]
                                      |)
                                    |)
                                  |)
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (let _ :=
                                  M.is_struct_tuple (|
                                    γ,
                                    "core::str::pattern::SearchStep::Done"
                                  |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.read (|
                                      M.return_ (|
                                        Value.StructTuple "core::option::Option::None" []
                                      |)
                                    |)
                                  |)
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (M.alloc (| M.never_to_any (| M.read (| M.continue (||) |) |) |)))
                          ]
                        |)))
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom ProvidedMethod_next_reject_back :
        M.IsProvidedMethod
          "core::str::pattern::ReverseSearcher"
          "next_reject_back"
          next_reject_back.
    End ReverseSearcher.
    
    (* Trait *)
    (* Empty module 'DoubleEndedSearcher' *)
    
    (* StructRecord
      {
        name := "CharSearcher";
        const_params := [];
        ty_params := [];
        fields :=
          [
            ("haystack", Ty.apply (Ty.path "&") [] [ Ty.path "str" ]);
            ("finger", Ty.path "usize");
            ("finger_back", Ty.path "usize");
            ("needle", Ty.path "char");
            ("utf8_size", Ty.path "u8");
            ("utf8_encoded",
              Ty.apply (Ty.path "array") [ Value.Integer IntegerKind.Usize 4 ] [ Ty.path "u8" ])
          ];
      } *)
    
    Module Impl_core_clone_Clone_for_core_str_pattern_CharSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSearcher".
      
      (* Clone *)
      Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructRecord
              "core::str::pattern::CharSearcher"
              [
                ("haystack",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::CharSearcher",
                        "haystack"
                      |)
                    ]
                  |));
                ("finger",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::CharSearcher",
                        "finger"
                      |)
                    ]
                  |));
                ("finger_back",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::CharSearcher",
                        "finger_back"
                      |)
                    ]
                  |));
                ("needle",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "char", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::CharSearcher",
                        "needle"
                      |)
                    ]
                  |));
                ("utf8_size",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "u8", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::CharSearcher",
                        "utf8_size"
                      |)
                    ]
                  |));
                ("utf8_encoded",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply
                        (Ty.path "array")
                        [ Value.Integer IntegerKind.Usize 4 ]
                        [ Ty.path "u8" ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::CharSearcher",
                        "utf8_encoded"
                      |)
                    ]
                  |))
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::clone::Clone"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method clone) ].
    End Impl_core_clone_Clone_for_core_str_pattern_CharSearcher.
    
    Module Impl_core_fmt_Debug_for_core_str_pattern_CharSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSearcher".
      
      (* Debug *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.read (|
              let~ names :=
                M.alloc (|
                  M.alloc (|
                    Value.Array
                      [
                        M.read (| Value.String "haystack" |);
                        M.read (| Value.String "finger" |);
                        M.read (| Value.String "finger_back" |);
                        M.read (| Value.String "needle" |);
                        M.read (| Value.String "utf8_size" |);
                        M.read (| Value.String "utf8_encoded" |)
                      ]
                  |)
                |) in
              let~ values :=
                M.alloc (|
                  M.alloc (|
                    Value.Array
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::CharSearcher",
                          "haystack"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::CharSearcher",
                          "finger"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::CharSearcher",
                          "finger_back"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::CharSearcher",
                          "needle"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::CharSearcher",
                          "utf8_size"
                        |);
                        M.alloc (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "core::str::pattern::CharSearcher",
                            "utf8_encoded"
                          |)
                        |)
                      ]
                  |)
                |) in
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "core::fmt::Formatter",
                    "debug_struct_fields_finish",
                    []
                  |),
                  [
                    M.read (| f |);
                    M.read (| Value.String "CharSearcher" |);
                    M.read (| names |);
                    M.read (| values |)
                  ]
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Debug"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Debug_for_core_str_pattern_CharSearcher.
    
    Module Impl_core_str_pattern_CharSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSearcher".
      
      (*
          fn utf8_size(&self) -> usize {
              self.utf8_size.into()
          }
      *)
      Definition utf8_size (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::convert::Into",
                Ty.path "u8",
                [ Ty.path "usize" ],
                "into",
                []
              |),
              [
                M.read (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::str::pattern::CharSearcher",
                    "utf8_size"
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_utf8_size : M.IsAssociatedFunction Self "utf8_size" utf8_size.
    End Impl_core_str_pattern_CharSearcher.
    
    Module Impl_core_str_pattern_Searcher_for_core_str_pattern_CharSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSearcher".
      
      (*
          fn haystack(&self) -> &'a str {
              self.haystack
          }
      *)
      Definition haystack (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.SubPointer.get_struct_record_field (|
                M.read (| self |),
                "core::str::pattern::CharSearcher",
                "haystack"
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn next(&mut self) -> SearchStep {
              let old_finger = self.finger;
              // SAFETY: 1-4 guarantee safety of `get_unchecked`
              // 1. `self.finger` and `self.finger_back` are kept on unicode boundaries
              //    (this is invariant)
              // 2. `self.finger >= 0` since it starts at 0 and only increases
              // 3. `self.finger < self.finger_back` because otherwise the char `iter`
              //    would return `SearchStep::Done`
              // 4. `self.finger` comes before the end of the haystack because `self.finger_back`
              //    starts at the end and only decreases
              let slice = unsafe { self.haystack.get_unchecked(old_finger..self.finger_back) };
              let mut iter = slice.chars();
              let old_len = iter.iter.len();
              if let Some(ch) = iter.next() {
                  // add byte offset of current character
                  // without re-encoding as utf-8
                  self.finger += old_len - iter.iter.len();
                  if ch == self.needle {
                      SearchStep::Match(old_finger, self.finger)
                  } else {
                      SearchStep::Reject(old_finger, self.finger)
                  }
              } else {
                  SearchStep::Done
              }
          }
      *)
      Definition next (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              let~ old_finger :=
                M.copy (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::str::pattern::CharSearcher",
                    "finger"
                  |)
                |) in
              let~ slice :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "str",
                      "get_unchecked",
                      [ Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ] ]
                    |),
                    [
                      M.read (|
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::CharSearcher",
                          "haystack"
                        |)
                      |);
                      Value.StructRecord
                        "core::ops::range::Range"
                        [
                          ("start", M.read (| old_finger |));
                          ("end_",
                            M.read (|
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "core::str::pattern::CharSearcher",
                                "finger_back"
                              |)
                            |))
                        ]
                    ]
                  |)
                |) in
              let~ iter :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (| Ty.path "str", "chars", [] |),
                    [ M.read (| slice |) ]
                  |)
                |) in
              let~ old_len :=
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::iter::traits::exact_size::ExactSizeIterator",
                      Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "u8" ],
                      [],
                      "len",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        iter,
                        "core::str::iter::Chars",
                        "iter"
                      |)
                    ]
                  |)
                |) in
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              Ty.path "core::str::iter::Chars",
                              [],
                              "next",
                              []
                            |),
                            [ iter ]
                          |)
                        |) in
                      let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::option::Option::Some",
                          0
                        |) in
                      let ch := M.copy (| γ0_0 |) in
                      let~ _ :=
                        let β :=
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "core::str::pattern::CharSearcher",
                            "finger"
                          |) in
                        M.write (|
                          β,
                          BinOp.Wrap.add (|
                            M.read (| β |),
                            BinOp.Wrap.sub (|
                              M.read (| old_len |),
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::exact_size::ExactSizeIterator",
                                  Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "u8" ],
                                  [],
                                  "len",
                                  []
                                |),
                                [
                                  M.SubPointer.get_struct_record_field (|
                                    iter,
                                    "core::str::iter::Chars",
                                    "iter"
                                  |)
                                ]
                              |)
                            |)
                          |)
                        |) in
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    BinOp.eq (|
                                      M.read (| ch |),
                                      M.read (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::CharSearcher",
                                          "needle"
                                        |)
                                      |)
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              M.alloc (|
                                Value.StructTuple
                                  "core::str::pattern::SearchStep::Match"
                                  [
                                    M.read (| old_finger |);
                                    M.read (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::str::pattern::CharSearcher",
                                        "finger"
                                      |)
                                    |)
                                  ]
                              |)));
                          fun γ =>
                            ltac:(M.monadic
                              (M.alloc (|
                                Value.StructTuple
                                  "core::str::pattern::SearchStep::Reject"
                                  [
                                    M.read (| old_finger |);
                                    M.read (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::str::pattern::CharSearcher",
                                        "finger"
                                      |)
                                    |)
                                  ]
                              |)))
                        ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (| Value.StructTuple "core::str::pattern::SearchStep::Done" [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn next_match(&mut self) -> Option<(usize, usize)> {
              loop {
                  // get the haystack after the last character found
                  let bytes = self.haystack.as_bytes().get(self.finger..self.finger_back)?;
                  // the last byte of the utf8 encoded needle
                  // SAFETY: we have an invariant that `utf8_size < 5`
                  let last_byte = unsafe { *self.utf8_encoded.get_unchecked(self.utf8_size() - 1) };
                  if let Some(index) = memchr::memchr(last_byte, bytes) {
                      // The new finger is the index of the byte we found,
                      // plus one, since we memchr'd for the last byte of the character.
                      //
                      // Note that this doesn't always give us a finger on a UTF8 boundary.
                      // If we *didn't* find our character
                      // we may have indexed to the non-last byte of a 3-byte or 4-byte character.
                      // We can't just skip to the next valid starting byte because a character like
                      // ꁁ (U+A041 YI SYLLABLE PA), utf-8 `EA 81 81` will have us always find
                      // the second byte when searching for the third.
                      //
                      // However, this is totally okay. While we have the invariant that
                      // self.finger is on a UTF8 boundary, this invariant is not relied upon
                      // within this method (it is relied upon in CharSearcher::next()).
                      //
                      // We only exit this method when we reach the end of the string, or if we
                      // find something. When we find something the `finger` will be set
                      // to a UTF8 boundary.
                      self.finger += index + 1;
                      if self.finger >= self.utf8_size() {
                          let found_char = self.finger - self.utf8_size();
                          if let Some(slice) = self.haystack.as_bytes().get(found_char..self.finger) {
                              if slice == &self.utf8_encoded[0..self.utf8_size()] {
                                  return Some((found_char, self.finger));
                              }
                          }
                      }
                  } else {
                      // found nothing, exit
                      self.finger = self.finger_back;
                      return None;
                  }
              }
          }
      *)
      Definition next_match (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.never_to_any (|
                  M.read (|
                    M.loop (|
                      ltac:(M.monadic
                        (let~ bytes :=
                          M.copy (|
                            M.match_operator (|
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::ops::try_trait::Try",
                                    Ty.apply
                                      (Ty.path "core::option::Option")
                                      []
                                      [
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [ Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ] ]
                                      ],
                                    [],
                                    "branch",
                                    []
                                  |),
                                  [
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                        "get",
                                        [
                                          Ty.apply
                                            (Ty.path "core::ops::range::Range")
                                            []
                                            [ Ty.path "usize" ]
                                        ]
                                      |),
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "str",
                                            "as_bytes",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::CharSearcher",
                                                "haystack"
                                              |)
                                            |)
                                          ]
                                        |);
                                        Value.StructRecord
                                          "core::ops::range::Range"
                                          [
                                            ("start",
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::CharSearcher",
                                                  "finger"
                                                |)
                                              |));
                                            ("end_",
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::CharSearcher",
                                                  "finger_back"
                                                |)
                                              |))
                                          ]
                                      ]
                                    |)
                                  ]
                                |)
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::ops::control_flow::ControlFlow::Break",
                                        0
                                      |) in
                                    let residual := M.copy (| γ0_0 |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::ops::try_trait::FromResidual",
                                                Ty.apply
                                                  (Ty.path "core::option::Option")
                                                  []
                                                  [ Ty.tuple [ Ty.path "usize"; Ty.path "usize" ] ],
                                                [
                                                  Ty.apply
                                                    (Ty.path "core::option::Option")
                                                    []
                                                    [ Ty.path "core::convert::Infallible" ]
                                                ],
                                                "from_residual",
                                                []
                                              |),
                                              [ M.read (| residual |) ]
                                            |)
                                          |)
                                        |)
                                      |)
                                    |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::ops::control_flow::ControlFlow::Continue",
                                        0
                                      |) in
                                    let val := M.copy (| γ0_0 |) in
                                    val))
                              ]
                            |)
                          |) in
                        let~ last_byte :=
                          M.copy (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                "get_unchecked",
                                [ Ty.path "usize" ]
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::str::pattern::CharSearcher",
                                  "utf8_encoded"
                                |);
                                BinOp.Wrap.sub (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "core::str::pattern::CharSearcher",
                                      "utf8_size",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |),
                                  Value.Integer IntegerKind.Usize 1
                                |)
                              ]
                            |)
                          |) in
                        M.match_operator (|
                          M.alloc (| Value.Tuple [] |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ :=
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (| "core::slice::memchr::memchr", [] |),
                                      [ M.read (| last_byte |); M.read (| bytes |) ]
                                    |)
                                  |) in
                                let γ0_0 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "core::option::Option::Some",
                                    0
                                  |) in
                                let index := M.copy (| γ0_0 |) in
                                let~ _ :=
                                  let β :=
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "core::str::pattern::CharSearcher",
                                      "finger"
                                    |) in
                                  M.write (|
                                    β,
                                    BinOp.Wrap.add (|
                                      M.read (| β |),
                                      BinOp.Wrap.add (|
                                        M.read (| index |),
                                        Value.Integer IntegerKind.Usize 1
                                      |)
                                    |)
                                  |) in
                                M.match_operator (|
                                  M.alloc (| Value.Tuple [] |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ :=
                                          M.use
                                            (M.alloc (|
                                              BinOp.ge (|
                                                M.read (|
                                                  M.SubPointer.get_struct_record_field (|
                                                    M.read (| self |),
                                                    "core::str::pattern::CharSearcher",
                                                    "finger"
                                                  |)
                                                |),
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "core::str::pattern::CharSearcher",
                                                    "utf8_size",
                                                    []
                                                  |),
                                                  [ M.read (| self |) ]
                                                |)
                                              |)
                                            |)) in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        let~ found_char :=
                                          M.alloc (|
                                            BinOp.Wrap.sub (|
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::CharSearcher",
                                                  "finger"
                                                |)
                                              |),
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "core::str::pattern::CharSearcher",
                                                  "utf8_size",
                                                  []
                                                |),
                                                [ M.read (| self |) ]
                                              |)
                                            |)
                                          |) in
                                        M.match_operator (|
                                          M.alloc (| Value.Tuple [] |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ :=
                                                  M.alloc (|
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.apply
                                                          (Ty.path "slice")
                                                          []
                                                          [ Ty.path "u8" ],
                                                        "get",
                                                        [
                                                          Ty.apply
                                                            (Ty.path "core::ops::range::Range")
                                                            []
                                                            [ Ty.path "usize" ]
                                                        ]
                                                      |),
                                                      [
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path "str",
                                                            "as_bytes",
                                                            []
                                                          |),
                                                          [
                                                            M.read (|
                                                              M.SubPointer.get_struct_record_field (|
                                                                M.read (| self |),
                                                                "core::str::pattern::CharSearcher",
                                                                "haystack"
                                                              |)
                                                            |)
                                                          ]
                                                        |);
                                                        Value.StructRecord
                                                          "core::ops::range::Range"
                                                          [
                                                            ("start", M.read (| found_char |));
                                                            ("end_",
                                                              M.read (|
                                                                M.SubPointer.get_struct_record_field (|
                                                                  M.read (| self |),
                                                                  "core::str::pattern::CharSearcher",
                                                                  "finger"
                                                                |)
                                                              |))
                                                          ]
                                                      ]
                                                    |)
                                                  |) in
                                                let γ0_0 :=
                                                  M.SubPointer.get_struct_tuple_field (|
                                                    γ,
                                                    "core::option::Option::Some",
                                                    0
                                                  |) in
                                                let slice := M.copy (| γ0_0 |) in
                                                M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ :=
                                                          M.use
                                                            (M.alloc (|
                                                              M.call_closure (|
                                                                M.get_trait_method (|
                                                                  "core::cmp::PartialEq",
                                                                  Ty.apply
                                                                    (Ty.path "&")
                                                                    []
                                                                    [
                                                                      Ty.apply
                                                                        (Ty.path "slice")
                                                                        []
                                                                        [ Ty.path "u8" ]
                                                                    ],
                                                                  [
                                                                    Ty.apply
                                                                      (Ty.path "&")
                                                                      []
                                                                      [
                                                                        Ty.apply
                                                                          (Ty.path "slice")
                                                                          []
                                                                          [ Ty.path "u8" ]
                                                                      ]
                                                                  ],
                                                                  "eq",
                                                                  []
                                                                |),
                                                                [
                                                                  slice;
                                                                  M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_trait_method (|
                                                                        "core::ops::index::Index",
                                                                        Ty.apply
                                                                          (Ty.path "array")
                                                                          [
                                                                            Value.Integer
                                                                              IntegerKind.Usize
                                                                              4
                                                                          ]
                                                                          [ Ty.path "u8" ],
                                                                        [
                                                                          Ty.apply
                                                                            (Ty.path
                                                                              "core::ops::range::Range")
                                                                            []
                                                                            [ Ty.path "usize" ]
                                                                        ],
                                                                        "index",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.SubPointer.get_struct_record_field (|
                                                                          M.read (| self |),
                                                                          "core::str::pattern::CharSearcher",
                                                                          "utf8_encoded"
                                                                        |);
                                                                        Value.StructRecord
                                                                          "core::ops::range::Range"
                                                                          [
                                                                            ("start",
                                                                              Value.Integer
                                                                                IntegerKind.Usize
                                                                                0);
                                                                            ("end_",
                                                                              M.call_closure (|
                                                                                M.get_associated_function (|
                                                                                  Ty.path
                                                                                    "core::str::pattern::CharSearcher",
                                                                                  "utf8_size",
                                                                                  []
                                                                                |),
                                                                                [ M.read (| self |)
                                                                                ]
                                                                              |))
                                                                          ]
                                                                      ]
                                                                    |)
                                                                  |)
                                                                ]
                                                              |)
                                                            |)) in
                                                        let _ :=
                                                          M.is_constant_or_break_match (|
                                                            M.read (| γ |),
                                                            Value.Bool true
                                                          |) in
                                                        M.alloc (|
                                                          M.never_to_any (|
                                                            M.read (|
                                                              M.return_ (|
                                                                Value.StructTuple
                                                                  "core::option::Option::Some"
                                                                  [
                                                                    Value.Tuple
                                                                      [
                                                                        M.read (| found_char |);
                                                                        M.read (|
                                                                          M.SubPointer.get_struct_record_field (|
                                                                            M.read (| self |),
                                                                            "core::str::pattern::CharSearcher",
                                                                            "finger"
                                                                          |)
                                                                        |)
                                                                      ]
                                                                  ]
                                                              |)
                                                            |)
                                                          |)
                                                        |)));
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (M.alloc (| Value.Tuple [] |)))
                                                  ]
                                                |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |)));
                                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                  ]
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (M.alloc (|
                                  M.never_to_any (|
                                    M.read (|
                                      let~ _ :=
                                        M.write (|
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "core::str::pattern::CharSearcher",
                                            "finger"
                                          |),
                                          M.read (|
                                            M.SubPointer.get_struct_record_field (|
                                              M.read (| self |),
                                              "core::str::pattern::CharSearcher",
                                              "finger_back"
                                            |)
                                          |)
                                        |) in
                                      M.return_ (|
                                        Value.StructTuple "core::option::Option::None" []
                                      |)
                                    |)
                                  |)
                                |)))
                          ]
                        |)))
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::Searcher"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("haystack", InstanceField.Method haystack);
            ("next", InstanceField.Method next);
            ("next_match", InstanceField.Method next_match)
          ].
    End Impl_core_str_pattern_Searcher_for_core_str_pattern_CharSearcher.
    
    Module Impl_core_str_pattern_ReverseSearcher_for_core_str_pattern_CharSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSearcher".
      
      (*
          fn next_back(&mut self) -> SearchStep {
              let old_finger = self.finger_back;
              // SAFETY: see the comment for next() above
              let slice = unsafe { self.haystack.get_unchecked(self.finger..old_finger) };
              let mut iter = slice.chars();
              let old_len = iter.iter.len();
              if let Some(ch) = iter.next_back() {
                  // subtract byte offset of current character
                  // without re-encoding as utf-8
                  self.finger_back -= old_len - iter.iter.len();
                  if ch == self.needle {
                      SearchStep::Match(self.finger_back, old_finger)
                  } else {
                      SearchStep::Reject(self.finger_back, old_finger)
                  }
              } else {
                  SearchStep::Done
              }
          }
      *)
      Definition next_back (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              let~ old_finger :=
                M.copy (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::str::pattern::CharSearcher",
                    "finger_back"
                  |)
                |) in
              let~ slice :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "str",
                      "get_unchecked",
                      [ Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ] ]
                    |),
                    [
                      M.read (|
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::CharSearcher",
                          "haystack"
                        |)
                      |);
                      Value.StructRecord
                        "core::ops::range::Range"
                        [
                          ("start",
                            M.read (|
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "core::str::pattern::CharSearcher",
                                "finger"
                              |)
                            |));
                          ("end_", M.read (| old_finger |))
                        ]
                    ]
                  |)
                |) in
              let~ iter :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (| Ty.path "str", "chars", [] |),
                    [ M.read (| slice |) ]
                  |)
                |) in
              let~ old_len :=
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::iter::traits::exact_size::ExactSizeIterator",
                      Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "u8" ],
                      [],
                      "len",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        iter,
                        "core::str::iter::Chars",
                        "iter"
                      |)
                    ]
                  |)
                |) in
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::double_ended::DoubleEndedIterator",
                              Ty.path "core::str::iter::Chars",
                              [],
                              "next_back",
                              []
                            |),
                            [ iter ]
                          |)
                        |) in
                      let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::option::Option::Some",
                          0
                        |) in
                      let ch := M.copy (| γ0_0 |) in
                      let~ _ :=
                        let β :=
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "core::str::pattern::CharSearcher",
                            "finger_back"
                          |) in
                        M.write (|
                          β,
                          BinOp.Wrap.sub (|
                            M.read (| β |),
                            BinOp.Wrap.sub (|
                              M.read (| old_len |),
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::exact_size::ExactSizeIterator",
                                  Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "u8" ],
                                  [],
                                  "len",
                                  []
                                |),
                                [
                                  M.SubPointer.get_struct_record_field (|
                                    iter,
                                    "core::str::iter::Chars",
                                    "iter"
                                  |)
                                ]
                              |)
                            |)
                          |)
                        |) in
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    BinOp.eq (|
                                      M.read (| ch |),
                                      M.read (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::CharSearcher",
                                          "needle"
                                        |)
                                      |)
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              M.alloc (|
                                Value.StructTuple
                                  "core::str::pattern::SearchStep::Match"
                                  [
                                    M.read (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::str::pattern::CharSearcher",
                                        "finger_back"
                                      |)
                                    |);
                                    M.read (| old_finger |)
                                  ]
                              |)));
                          fun γ =>
                            ltac:(M.monadic
                              (M.alloc (|
                                Value.StructTuple
                                  "core::str::pattern::SearchStep::Reject"
                                  [
                                    M.read (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "core::str::pattern::CharSearcher",
                                        "finger_back"
                                      |)
                                    |);
                                    M.read (| old_finger |)
                                  ]
                              |)))
                        ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (| Value.StructTuple "core::str::pattern::SearchStep::Done" [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn next_match_back(&mut self) -> Option<(usize, usize)> {
              let haystack = self.haystack.as_bytes();
              loop {
                  // get the haystack up to but not including the last character searched
                  let bytes = haystack.get(self.finger..self.finger_back)?;
                  // the last byte of the utf8 encoded needle
                  // SAFETY: we have an invariant that `utf8_size < 5`
                  let last_byte = unsafe { *self.utf8_encoded.get_unchecked(self.utf8_size() - 1) };
                  if let Some(index) = memchr::memrchr(last_byte, bytes) {
                      // we searched a slice that was offset by self.finger,
                      // add self.finger to recoup the original index
                      let index = self.finger + index;
                      // memrchr will return the index of the byte we wish to
                      // find. In case of an ASCII character, this is indeed
                      // were we wish our new finger to be ("after" the found
                      // char in the paradigm of reverse iteration). For
                      // multibyte chars we need to skip down by the number of more
                      // bytes they have than ASCII
                      let shift = self.utf8_size() - 1;
                      if index >= shift {
                          let found_char = index - shift;
                          if let Some(slice) = haystack.get(found_char..(found_char + self.utf8_size())) {
                              if slice == &self.utf8_encoded[0..self.utf8_size()] {
                                  // move finger to before the character found (i.e., at its start index)
                                  self.finger_back = found_char;
                                  return Some((self.finger_back, self.finger_back + self.utf8_size()));
                              }
                          }
                      }
                      // We can't use finger_back = index - size + 1 here. If we found the last char
                      // of a different-sized character (or the middle byte of a different character)
                      // we need to bump the finger_back down to `index`. This similarly makes
                      // `finger_back` have the potential to no longer be on a boundary,
                      // but this is OK since we only exit this function on a boundary
                      // or when the haystack has been searched completely.
                      //
                      // Unlike next_match this does not
                      // have the problem of repeated bytes in utf-8 because
                      // we're searching for the last byte, and we can only have
                      // found the last byte when searching in reverse.
                      self.finger_back = index;
                  } else {
                      self.finger_back = self.finger;
                      // found nothing, exit
                      return None;
                  }
              }
          }
      *)
      Definition next_match_back (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ haystack :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                        [
                          M.read (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "core::str::pattern::CharSearcher",
                              "haystack"
                            |)
                          |)
                        ]
                      |)
                    |) in
                  M.alloc (|
                    M.never_to_any (|
                      M.read (|
                        M.loop (|
                          ltac:(M.monadic
                            (let~ bytes :=
                              M.copy (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::Try",
                                        Ty.apply
                                          (Ty.path "core::option::Option")
                                          []
                                          [
                                            Ty.apply
                                              (Ty.path "&")
                                              []
                                              [ Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ] ]
                                          ],
                                        [],
                                        "branch",
                                        []
                                      |),
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                            "get",
                                            [
                                              Ty.apply
                                                (Ty.path "core::ops::range::Range")
                                                []
                                                [ Ty.path "usize" ]
                                            ]
                                          |),
                                          [
                                            M.read (| haystack |);
                                            Value.StructRecord
                                              "core::ops::range::Range"
                                              [
                                                ("start",
                                                  M.read (|
                                                    M.SubPointer.get_struct_record_field (|
                                                      M.read (| self |),
                                                      "core::str::pattern::CharSearcher",
                                                      "finger"
                                                    |)
                                                  |));
                                                ("end_",
                                                  M.read (|
                                                    M.SubPointer.get_struct_record_field (|
                                                      M.read (| self |),
                                                      "core::str::pattern::CharSearcher",
                                                      "finger_back"
                                                    |)
                                                  |))
                                              ]
                                          ]
                                        |)
                                      ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::ops::control_flow::ControlFlow::Break",
                                            0
                                          |) in
                                        let residual := M.copy (| γ0_0 |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::ops::try_trait::FromResidual",
                                                    Ty.apply
                                                      (Ty.path "core::option::Option")
                                                      []
                                                      [
                                                        Ty.tuple
                                                          [ Ty.path "usize"; Ty.path "usize" ]
                                                      ],
                                                    [
                                                      Ty.apply
                                                        (Ty.path "core::option::Option")
                                                        []
                                                        [ Ty.path "core::convert::Infallible" ]
                                                    ],
                                                    "from_residual",
                                                    []
                                                  |),
                                                  [ M.read (| residual |) ]
                                                |)
                                              |)
                                            |)
                                          |)
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::ops::control_flow::ControlFlow::Continue",
                                            0
                                          |) in
                                        let val := M.copy (| γ0_0 |) in
                                        val))
                                  ]
                                |)
                              |) in
                            let~ last_byte :=
                              M.copy (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                    "get_unchecked",
                                    [ Ty.path "usize" ]
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "core::str::pattern::CharSearcher",
                                      "utf8_encoded"
                                    |);
                                    BinOp.Wrap.sub (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "core::str::pattern::CharSearcher",
                                          "utf8_size",
                                          []
                                        |),
                                        [ M.read (| self |) ]
                                      |),
                                      Value.Integer IntegerKind.Usize 1
                                    |)
                                  ]
                                |)
                              |) in
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_function (| "core::slice::memchr::memrchr", [] |),
                                          [ M.read (| last_byte |); M.read (| bytes |) ]
                                        |)
                                      |) in
                                    let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::option::Option::Some",
                                        0
                                      |) in
                                    let index := M.copy (| γ0_0 |) in
                                    let~ index :=
                                      M.alloc (|
                                        BinOp.Wrap.add (|
                                          M.read (|
                                            M.SubPointer.get_struct_record_field (|
                                              M.read (| self |),
                                              "core::str::pattern::CharSearcher",
                                              "finger"
                                            |)
                                          |),
                                          M.read (| index |)
                                        |)
                                      |) in
                                    let~ shift :=
                                      M.alloc (|
                                        BinOp.Wrap.sub (|
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "core::str::pattern::CharSearcher",
                                              "utf8_size",
                                              []
                                            |),
                                            [ M.read (| self |) ]
                                          |),
                                          Value.Integer IntegerKind.Usize 1
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.ge (|
                                                      M.read (| index |),
                                                      M.read (| shift |)
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              let~ found_char :=
                                                M.alloc (|
                                                  BinOp.Wrap.sub (|
                                                    M.read (| index |),
                                                    M.read (| shift |)
                                                  |)
                                                |) in
                                              M.match_operator (|
                                                M.alloc (| Value.Tuple [] |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ :=
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path "slice")
                                                                []
                                                                [ Ty.path "u8" ],
                                                              "get",
                                                              [
                                                                Ty.apply
                                                                  (Ty.path
                                                                    "core::ops::range::Range")
                                                                  []
                                                                  [ Ty.path "usize" ]
                                                              ]
                                                            |),
                                                            [
                                                              M.read (| haystack |);
                                                              Value.StructRecord
                                                                "core::ops::range::Range"
                                                                [
                                                                  ("start",
                                                                    M.read (| found_char |));
                                                                  ("end_",
                                                                    BinOp.Wrap.add (|
                                                                      M.read (| found_char |),
                                                                      M.call_closure (|
                                                                        M.get_associated_function (|
                                                                          Ty.path
                                                                            "core::str::pattern::CharSearcher",
                                                                          "utf8_size",
                                                                          []
                                                                        |),
                                                                        [ M.read (| self |) ]
                                                                      |)
                                                                    |))
                                                                ]
                                                            ]
                                                          |)
                                                        |) in
                                                      let γ0_0 :=
                                                        M.SubPointer.get_struct_tuple_field (|
                                                          γ,
                                                          "core::option::Option::Some",
                                                          0
                                                        |) in
                                                      let slice := M.copy (| γ0_0 |) in
                                                      M.match_operator (|
                                                        M.alloc (| Value.Tuple [] |),
                                                        [
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (let γ :=
                                                                M.use
                                                                  (M.alloc (|
                                                                    M.call_closure (|
                                                                      M.get_trait_method (|
                                                                        "core::cmp::PartialEq",
                                                                        Ty.apply
                                                                          (Ty.path "&")
                                                                          []
                                                                          [
                                                                            Ty.apply
                                                                              (Ty.path "slice")
                                                                              []
                                                                              [ Ty.path "u8" ]
                                                                          ],
                                                                        [
                                                                          Ty.apply
                                                                            (Ty.path "&")
                                                                            []
                                                                            [
                                                                              Ty.apply
                                                                                (Ty.path "slice")
                                                                                []
                                                                                [ Ty.path "u8" ]
                                                                            ]
                                                                        ],
                                                                        "eq",
                                                                        []
                                                                      |),
                                                                      [
                                                                        slice;
                                                                        M.alloc (|
                                                                          M.call_closure (|
                                                                            M.get_trait_method (|
                                                                              "core::ops::index::Index",
                                                                              Ty.apply
                                                                                (Ty.path "array")
                                                                                [
                                                                                  Value.Integer
                                                                                    IntegerKind.Usize
                                                                                    4
                                                                                ]
                                                                                [ Ty.path "u8" ],
                                                                              [
                                                                                Ty.apply
                                                                                  (Ty.path
                                                                                    "core::ops::range::Range")
                                                                                  []
                                                                                  [ Ty.path "usize"
                                                                                  ]
                                                                              ],
                                                                              "index",
                                                                              []
                                                                            |),
                                                                            [
                                                                              M.SubPointer.get_struct_record_field (|
                                                                                M.read (| self |),
                                                                                "core::str::pattern::CharSearcher",
                                                                                "utf8_encoded"
                                                                              |);
                                                                              Value.StructRecord
                                                                                "core::ops::range::Range"
                                                                                [
                                                                                  ("start",
                                                                                    Value.Integer
                                                                                      IntegerKind.Usize
                                                                                      0);
                                                                                  ("end_",
                                                                                    M.call_closure (|
                                                                                      M.get_associated_function (|
                                                                                        Ty.path
                                                                                          "core::str::pattern::CharSearcher",
                                                                                        "utf8_size",
                                                                                        []
                                                                                      |),
                                                                                      [
                                                                                        M.read (|
                                                                                          self
                                                                                        |)
                                                                                      ]
                                                                                    |))
                                                                                ]
                                                                            ]
                                                                          |)
                                                                        |)
                                                                      ]
                                                                    |)
                                                                  |)) in
                                                              let _ :=
                                                                M.is_constant_or_break_match (|
                                                                  M.read (| γ |),
                                                                  Value.Bool true
                                                                |) in
                                                              M.alloc (|
                                                                M.never_to_any (|
                                                                  M.read (|
                                                                    let~ _ :=
                                                                      M.write (|
                                                                        M.SubPointer.get_struct_record_field (|
                                                                          M.read (| self |),
                                                                          "core::str::pattern::CharSearcher",
                                                                          "finger_back"
                                                                        |),
                                                                        M.read (| found_char |)
                                                                      |) in
                                                                    M.return_ (|
                                                                      Value.StructTuple
                                                                        "core::option::Option::Some"
                                                                        [
                                                                          Value.Tuple
                                                                            [
                                                                              M.read (|
                                                                                M.SubPointer.get_struct_record_field (|
                                                                                  M.read (| self |),
                                                                                  "core::str::pattern::CharSearcher",
                                                                                  "finger_back"
                                                                                |)
                                                                              |);
                                                                              BinOp.Wrap.add (|
                                                                                M.read (|
                                                                                  M.SubPointer.get_struct_record_field (|
                                                                                    M.read (|
                                                                                      self
                                                                                    |),
                                                                                    "core::str::pattern::CharSearcher",
                                                                                    "finger_back"
                                                                                  |)
                                                                                |),
                                                                                M.call_closure (|
                                                                                  M.get_associated_function (|
                                                                                    Ty.path
                                                                                      "core::str::pattern::CharSearcher",
                                                                                    "utf8_size",
                                                                                    []
                                                                                  |),
                                                                                  [
                                                                                    M.read (|
                                                                                      self
                                                                                    |)
                                                                                  ]
                                                                                |)
                                                                              |)
                                                                            ]
                                                                        ]
                                                                    |)
                                                                  |)
                                                                |)
                                                              |)));
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (M.alloc (| Value.Tuple [] |)))
                                                        ]
                                                      |)));
                                                  fun γ =>
                                                    ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                                ]
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |) in
                                    let~ _ :=
                                      M.write (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::CharSearcher",
                                          "finger_back"
                                        |),
                                        M.read (| index |)
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          let~ _ :=
                                            M.write (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::CharSearcher",
                                                "finger_back"
                                              |),
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::CharSearcher",
                                                  "finger"
                                                |)
                                              |)
                                            |) in
                                          M.return_ (|
                                            Value.StructTuple "core::option::Option::None" []
                                          |)
                                        |)
                                      |)
                                    |)))
                              ]
                            |)))
                        |)
                      |)
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::ReverseSearcher"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("next_back", InstanceField.Method next_back);
            ("next_match_back", InstanceField.Method next_match_back)
          ].
    End Impl_core_str_pattern_ReverseSearcher_for_core_str_pattern_CharSearcher.
    
    Module Impl_core_str_pattern_DoubleEndedSearcher_for_core_str_pattern_CharSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSearcher".
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::DoubleEndedSearcher"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_str_pattern_DoubleEndedSearcher_for_core_str_pattern_CharSearcher.
    
    Module Impl_core_str_pattern_Pattern_for_char.
      Definition Self : Ty.t := Ty.path "char".
      
      (*     type Searcher<'a> = CharSearcher<'a>; *)
      Definition _Searcher : Ty.t := Ty.path "core::str::pattern::CharSearcher".
      
      (*
          fn into_searcher(self, haystack: &str) -> Self::Searcher<'_> {
              let mut utf8_encoded = [0; 4];
              let utf8_size = self
                  .encode_utf8(&mut utf8_encoded)
                  .len()
                  .try_into()
                  .expect("char len should be less than 255");
      
              CharSearcher {
                  haystack,
                  finger: 0,
                  finger_back: haystack.len(),
                  needle: self,
                  utf8_size,
                  utf8_encoded,
              }
          }
      *)
      Definition into_searcher (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.read (|
              let~ utf8_encoded :=
                M.alloc (|
                  repeat (| Value.Integer IntegerKind.U8 0, Value.Integer IntegerKind.Usize 4 |)
                |) in
              let~ utf8_size :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "core::result::Result")
                        []
                        [ Ty.path "u8"; Ty.path "core::num::error::TryFromIntError" ],
                      "expect",
                      []
                    |),
                    [
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::convert::TryInto",
                          Ty.path "usize",
                          [ Ty.path "u8" ],
                          "try_into",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (| Ty.path "str", "len", [] |),
                            [
                              M.call_closure (|
                                M.get_associated_function (| Ty.path "char", "encode_utf8", [] |),
                                [ M.read (| self |); utf8_encoded ]
                              |)
                            ]
                          |)
                        ]
                      |);
                      M.read (| Value.String "char len should be less than 255" |)
                    ]
                  |)
                |) in
              M.alloc (|
                Value.StructRecord
                  "core::str::pattern::CharSearcher"
                  [
                    ("haystack", M.read (| haystack |));
                    ("finger", Value.Integer IntegerKind.Usize 0);
                    ("finger_back",
                      M.call_closure (|
                        M.get_associated_function (| Ty.path "str", "len", [] |),
                        [ M.read (| haystack |) ]
                      |));
                    ("needle", M.read (| self |));
                    ("utf8_size", M.read (| utf8_size |));
                    ("utf8_encoded", M.read (| utf8_encoded |))
                  ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn is_contained_in(self, haystack: &str) -> bool {
              if (self as u32) < 128 {
                  haystack.as_bytes().contains(&(self as u8))
              } else {
                  let mut buffer = [0u8; 4];
                  self.encode_utf8(&mut buffer).is_contained_in(haystack)
              }
          }
      *)
      Definition is_contained_in (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.read (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            BinOp.lt (|
                              M.rust_cast (M.read (| self |)),
                              Value.Integer IntegerKind.U32 128
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                            "contains",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                              [ M.read (| haystack |) ]
                            |);
                            M.alloc (| M.rust_cast (M.read (| self |)) |)
                          ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let~ buffer :=
                        M.alloc (|
                          repeat (|
                            Value.Integer IntegerKind.U8 0,
                            Value.Integer IntegerKind.Usize 4
                          |)
                        |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::str::pattern::Pattern",
                            Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                            [],
                            "is_contained_in",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "char", "encode_utf8", [] |),
                              [ M.read (| self |); buffer ]
                            |);
                            M.read (| haystack |)
                          ]
                        |)
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn is_prefix_of(self, haystack: &str) -> bool {
              self.encode_utf8(&mut [0u8; 4]).is_prefix_of(haystack)
          }
      *)
      Definition is_prefix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                [],
                "is_prefix_of",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (| Ty.path "char", "encode_utf8", [] |),
                  [
                    M.read (| self |);
                    M.alloc (|
                      repeat (| Value.Integer IntegerKind.U8 0, Value.Integer IntegerKind.Usize 4 |)
                    |)
                  ]
                |);
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn strip_prefix_of(self, haystack: &str) -> Option<&str> {
              self.encode_utf8(&mut [0u8; 4]).strip_prefix_of(haystack)
          }
      *)
      Definition strip_prefix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                [],
                "strip_prefix_of",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (| Ty.path "char", "encode_utf8", [] |),
                  [
                    M.read (| self |);
                    M.alloc (|
                      repeat (| Value.Integer IntegerKind.U8 0, Value.Integer IntegerKind.Usize 4 |)
                    |)
                  ]
                |);
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn is_suffix_of<'a>(self, haystack: &'a str) -> bool
          where
              Self::Searcher<'a>: ReverseSearcher<'a>,
          {
              self.encode_utf8(&mut [0u8; 4]).is_suffix_of(haystack)
          }
      *)
      Definition is_suffix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                [],
                "is_suffix_of",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (| Ty.path "char", "encode_utf8", [] |),
                  [
                    M.read (| self |);
                    M.alloc (|
                      repeat (| Value.Integer IntegerKind.U8 0, Value.Integer IntegerKind.Usize 4 |)
                    |)
                  ]
                |);
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
          where
              Self::Searcher<'a>: ReverseSearcher<'a>,
          {
              self.encode_utf8(&mut [0u8; 4]).strip_suffix_of(haystack)
          }
      *)
      Definition strip_suffix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                [],
                "strip_suffix_of",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (| Ty.path "char", "encode_utf8", [] |),
                  [
                    M.read (| self |);
                    M.alloc (|
                      repeat (| Value.Integer IntegerKind.U8 0, Value.Integer IntegerKind.Usize 4 |)
                    |)
                  ]
                |);
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::Pattern"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Searcher", InstanceField.Ty _Searcher);
            ("into_searcher", InstanceField.Method into_searcher);
            ("is_contained_in", InstanceField.Method is_contained_in);
            ("is_prefix_of", InstanceField.Method is_prefix_of);
            ("strip_prefix_of", InstanceField.Method strip_prefix_of);
            ("is_suffix_of", InstanceField.Method is_suffix_of);
            ("strip_suffix_of", InstanceField.Method strip_suffix_of)
          ].
    End Impl_core_str_pattern_Pattern_for_char.
    
    (* Trait *)
    (* Empty module 'MultiCharEq' *)
    
    Module Impl_core_str_pattern_MultiCharEq_where_core_ops_function_FnMut_F_Tuple_char__for_F.
      Definition Self (F : Ty.t) : Ty.t := F.
      
      (*
          fn matches(&mut self, c: char) -> bool {
              ( *self)(c)
          }
      *)
      Definition matches (F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self; c ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let c := M.alloc (| c |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::ops::function::FnMut",
                F,
                [ Ty.tuple [ Ty.path "char" ] ],
                "call_mut",
                []
              |),
              [ M.read (| self |); Value.Tuple [ M.read (| c |) ] ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (F : Ty.t),
        M.IsTraitInstance
          "core::str::pattern::MultiCharEq"
          (Self F)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("matches", InstanceField.Method (matches F)) ].
    End Impl_core_str_pattern_MultiCharEq_where_core_ops_function_FnMut_F_Tuple_char__for_F.
    
    Module Impl_core_str_pattern_MultiCharEq_for_array_N_char.
      Definition Self (N : Value.t) : Ty.t := Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ].
      
      (*
          fn matches(&mut self, c: char) -> bool {
              self.iter().any(|&m| m == c)
          }
      *)
      Definition matches (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; c ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let c := M.alloc (| c |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::iter::traits::iterator::Iterator",
                Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "char" ],
                [],
                "any",
                [
                  Ty.function
                    [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ Ty.path "char" ] ] ]
                    (Ty.path "bool")
                ]
              |),
              [
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "slice") [] [ Ty.path "char" ],
                      "iter",
                      []
                    |),
                    [ M.read (| self |) ]
                  |)
                |);
                M.closure
                  (fun γ =>
                    ltac:(M.monadic
                      match γ with
                      | [ α0 ] =>
                        ltac:(M.monadic
                          (M.match_operator (|
                            M.alloc (| α0 |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ := M.read (| γ |) in
                                  let m := M.copy (| γ |) in
                                  BinOp.eq (| M.read (| m |), M.read (| c |) |)))
                            ]
                          |)))
                      | _ => M.impossible "wrong number of arguments"
                      end))
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::str::pattern::MultiCharEq"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("matches", InstanceField.Method (matches N)) ].
    End Impl_core_str_pattern_MultiCharEq_for_array_N_char.
    
    Module Impl_core_str_pattern_MultiCharEq_for_ref__array_N_char.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ].
      
      (*
          fn matches(&mut self, c: char) -> bool {
              self.iter().any(|&m| m == c)
          }
      *)
      Definition matches (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; c ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let c := M.alloc (| c |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::iter::traits::iterator::Iterator",
                Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "char" ],
                [],
                "any",
                [
                  Ty.function
                    [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ Ty.path "char" ] ] ]
                    (Ty.path "bool")
                ]
              |),
              [
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "slice") [] [ Ty.path "char" ],
                      "iter",
                      []
                    |),
                    [ M.read (| M.read (| self |) |) ]
                  |)
                |);
                M.closure
                  (fun γ =>
                    ltac:(M.monadic
                      match γ with
                      | [ α0 ] =>
                        ltac:(M.monadic
                          (M.match_operator (|
                            M.alloc (| α0 |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ := M.read (| γ |) in
                                  let m := M.copy (| γ |) in
                                  BinOp.eq (| M.read (| m |), M.read (| c |) |)))
                            ]
                          |)))
                      | _ => M.impossible "wrong number of arguments"
                      end))
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::str::pattern::MultiCharEq"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("matches", InstanceField.Method (matches N)) ].
    End Impl_core_str_pattern_MultiCharEq_for_ref__array_N_char.
    
    Module Impl_core_str_pattern_MultiCharEq_for_ref__slice_char.
      Definition Self : Ty.t :=
        Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ].
      
      (*
          fn matches(&mut self, c: char) -> bool {
              self.iter().any(|&m| m == c)
          }
      *)
      Definition matches (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; c ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let c := M.alloc (| c |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::iter::traits::iterator::Iterator",
                Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "char" ],
                [],
                "any",
                [
                  Ty.function
                    [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ Ty.path "char" ] ] ]
                    (Ty.path "bool")
                ]
              |),
              [
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "slice") [] [ Ty.path "char" ],
                      "iter",
                      []
                    |),
                    [ M.read (| M.read (| self |) |) ]
                  |)
                |);
                M.closure
                  (fun γ =>
                    ltac:(M.monadic
                      match γ with
                      | [ α0 ] =>
                        ltac:(M.monadic
                          (M.match_operator (|
                            M.alloc (| α0 |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ := M.read (| γ |) in
                                  let m := M.copy (| γ |) in
                                  BinOp.eq (| M.read (| m |), M.read (| c |) |)))
                            ]
                          |)))
                      | _ => M.impossible "wrong number of arguments"
                      end))
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::MultiCharEq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("matches", InstanceField.Method matches) ].
    End Impl_core_str_pattern_MultiCharEq_for_ref__slice_char.
    
    (* StructTuple
      {
        name := "MultiCharEqPattern";
        const_params := [];
        ty_params := [ "C" ];
        fields := [ C ];
      } *)
    
    (* StructRecord
      {
        name := "MultiCharEqSearcher";
        const_params := [];
        ty_params := [ "C" ];
        fields :=
          [
            ("char_eq", C);
            ("haystack", Ty.apply (Ty.path "&") [] [ Ty.path "str" ]);
            ("char_indices", Ty.path "core::str::iter::CharIndices")
          ];
      } *)
    
    Module Impl_core_clone_Clone_where_core_clone_Clone_C_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqSearcher_C.
      Definition Self (C : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ C ].
      
      (* Clone *)
      Definition clone (C : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self C in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructRecord
              "core::str::pattern::MultiCharEqSearcher"
              [
                ("char_eq",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", C, [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::MultiCharEqSearcher",
                        "char_eq"
                      |)
                    ]
                  |));
                ("haystack",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::MultiCharEqSearcher",
                        "haystack"
                      |)
                    ]
                  |));
                ("char_indices",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.path "core::str::iter::CharIndices",
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::MultiCharEqSearcher",
                        "char_indices"
                      |)
                    ]
                  |))
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (C : Ty.t),
        M.IsTraitInstance
          "core::clone::Clone"
          (Self C)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method (clone C)) ].
    End Impl_core_clone_Clone_where_core_clone_Clone_C_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqSearcher_C.
    
    Module Impl_core_fmt_Debug_where_core_fmt_Debug_C_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqSearcher_C.
      Definition Self (C : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ C ].
      
      (* Debug *)
      Definition fmt (C : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self C 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_field3_finish",
                []
              |),
              [
                M.read (| f |);
                M.read (| Value.String "MultiCharEqSearcher" |);
                M.read (| Value.String "char_eq" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::str::pattern::MultiCharEqSearcher",
                  "char_eq"
                |);
                M.read (| Value.String "haystack" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::str::pattern::MultiCharEqSearcher",
                  "haystack"
                |);
                M.read (| Value.String "char_indices" |);
                M.alloc (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::str::pattern::MultiCharEqSearcher",
                    "char_indices"
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (C : Ty.t),
        M.IsTraitInstance
          "core::fmt::Debug"
          (Self C)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method (fmt C)) ].
    End Impl_core_fmt_Debug_where_core_fmt_Debug_C_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqSearcher_C.
    
    Module Impl_core_str_pattern_Pattern_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqPattern_C.
      Definition Self (C : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::MultiCharEqPattern") [] [ C ].
      
      (*     type Searcher<'a> = MultiCharEqSearcher<'a, C>; *)
      Definition _Searcher (C : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ C ].
      
      (*
          fn into_searcher(self, haystack: &str) -> MultiCharEqSearcher<'_, C> {
              MultiCharEqSearcher { haystack, char_eq: self.0, char_indices: haystack.char_indices() }
          }
      *)
      Definition into_searcher
          (C : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self C in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            Value.StructRecord
              "core::str::pattern::MultiCharEqSearcher"
              [
                ("haystack", M.read (| haystack |));
                ("char_eq",
                  M.read (|
                    M.SubPointer.get_struct_tuple_field (|
                      self,
                      "core::str::pattern::MultiCharEqPattern",
                      0
                    |)
                  |));
                ("char_indices",
                  M.call_closure (|
                    M.get_associated_function (| Ty.path "str", "char_indices", [] |),
                    [ M.read (| haystack |) ]
                  |))
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (C : Ty.t),
        M.IsTraitInstance
          "core::str::pattern::Pattern"
          (Self C)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Searcher", InstanceField.Ty (_Searcher C));
            ("into_searcher", InstanceField.Method (into_searcher C))
          ].
    End Impl_core_str_pattern_Pattern_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqPattern_C.
    
    Module Impl_core_str_pattern_Searcher_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqSearcher_C.
      Definition Self (C : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ C ].
      
      (*
          fn haystack(&self) -> &'a str {
              self.haystack
          }
      *)
      Definition haystack (C : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self C in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.SubPointer.get_struct_record_field (|
                M.read (| self |),
                "core::str::pattern::MultiCharEqSearcher",
                "haystack"
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn next(&mut self) -> SearchStep {
              let s = &mut self.char_indices;
              // Compare lengths of the internal byte slice iterator
              // to find length of current char
              let pre_len = s.iter.iter.len();
              if let Some((i, c)) = s.next() {
                  let len = s.iter.iter.len();
                  let char_len = pre_len - len;
                  if self.char_eq.matches(c) {
                      return SearchStep::Match(i, i + char_len);
                  } else {
                      return SearchStep::Reject(i, i + char_len);
                  }
              }
              SearchStep::Done
          }
      *)
      Definition next (C : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self C in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ s :=
                    M.alloc (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::MultiCharEqSearcher",
                        "char_indices"
                      |)
                    |) in
                  let~ pre_len :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::exact_size::ExactSizeIterator",
                          Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "u8" ],
                          [],
                          "len",
                          []
                        |),
                        [
                          M.SubPointer.get_struct_record_field (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| s |),
                              "core::str::iter::CharIndices",
                              "iter"
                            |),
                            "core::str::iter::Chars",
                            "iter"
                          |)
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::iter::traits::iterator::Iterator",
                                    Ty.path "core::str::iter::CharIndices",
                                    [],
                                    "next",
                                    []
                                  |),
                                  [ M.read (| s |) ]
                                |)
                              |) in
                            let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let γ1_0 := M.SubPointer.get_tuple_field (| γ0_0, 0 |) in
                            let γ1_1 := M.SubPointer.get_tuple_field (| γ0_0, 1 |) in
                            let i := M.copy (| γ1_0 |) in
                            let c := M.copy (| γ1_1 |) in
                            let~ len :=
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::iter::traits::exact_size::ExactSizeIterator",
                                    Ty.apply
                                      (Ty.path "core::slice::iter::Iter")
                                      []
                                      [ Ty.path "u8" ],
                                    [],
                                    "len",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| s |),
                                        "core::str::iter::CharIndices",
                                        "iter"
                                      |),
                                      "core::str::iter::Chars",
                                      "iter"
                                    |)
                                  ]
                                |)
                              |) in
                            let~ char_len :=
                              M.alloc (|
                                BinOp.Wrap.sub (| M.read (| pre_len |), M.read (| len |) |)
                              |) in
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::str::pattern::MultiCharEq",
                                              C,
                                              [],
                                              "matches",
                                              []
                                            |),
                                            [
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::MultiCharEqSearcher",
                                                "char_eq"
                                              |);
                                              M.read (| c |)
                                            ]
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            Value.StructTuple
                                              "core::str::pattern::SearchStep::Match"
                                              [
                                                M.read (| i |);
                                                BinOp.Wrap.add (|
                                                  M.read (| i |),
                                                  M.read (| char_len |)
                                                |)
                                              ]
                                          |)
                                        |)
                                      |)
                                    |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            Value.StructTuple
                                              "core::str::pattern::SearchStep::Reject"
                                              [
                                                M.read (| i |);
                                                BinOp.Wrap.add (|
                                                  M.read (| i |),
                                                  M.read (| char_len |)
                                                |)
                                              ]
                                          |)
                                        |)
                                      |)
                                    |)))
                              ]
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  M.alloc (| Value.StructTuple "core::str::pattern::SearchStep::Done" [] |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (C : Ty.t),
        M.IsTraitInstance
          "core::str::pattern::Searcher"
          (Self C)
          (* Trait polymorphic types *) []
          (* Instance *)
          [ ("haystack", InstanceField.Method (haystack C)); ("next", InstanceField.Method (next C))
          ].
    End Impl_core_str_pattern_Searcher_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqSearcher_C.
    
    Module Impl_core_str_pattern_ReverseSearcher_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqSearcher_C.
      Definition Self (C : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ C ].
      
      (*
          fn next_back(&mut self) -> SearchStep {
              let s = &mut self.char_indices;
              // Compare lengths of the internal byte slice iterator
              // to find length of current char
              let pre_len = s.iter.iter.len();
              if let Some((i, c)) = s.next_back() {
                  let len = s.iter.iter.len();
                  let char_len = pre_len - len;
                  if self.char_eq.matches(c) {
                      return SearchStep::Match(i, i + char_len);
                  } else {
                      return SearchStep::Reject(i, i + char_len);
                  }
              }
              SearchStep::Done
          }
      *)
      Definition next_back (C : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self C in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ s :=
                    M.alloc (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::MultiCharEqSearcher",
                        "char_indices"
                      |)
                    |) in
                  let~ pre_len :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::exact_size::ExactSizeIterator",
                          Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "u8" ],
                          [],
                          "len",
                          []
                        |),
                        [
                          M.SubPointer.get_struct_record_field (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| s |),
                              "core::str::iter::CharIndices",
                              "iter"
                            |),
                            "core::str::iter::Chars",
                            "iter"
                          |)
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::iter::traits::double_ended::DoubleEndedIterator",
                                    Ty.path "core::str::iter::CharIndices",
                                    [],
                                    "next_back",
                                    []
                                  |),
                                  [ M.read (| s |) ]
                                |)
                              |) in
                            let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let γ1_0 := M.SubPointer.get_tuple_field (| γ0_0, 0 |) in
                            let γ1_1 := M.SubPointer.get_tuple_field (| γ0_0, 1 |) in
                            let i := M.copy (| γ1_0 |) in
                            let c := M.copy (| γ1_1 |) in
                            let~ len :=
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::iter::traits::exact_size::ExactSizeIterator",
                                    Ty.apply
                                      (Ty.path "core::slice::iter::Iter")
                                      []
                                      [ Ty.path "u8" ],
                                    [],
                                    "len",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| s |),
                                        "core::str::iter::CharIndices",
                                        "iter"
                                      |),
                                      "core::str::iter::Chars",
                                      "iter"
                                    |)
                                  ]
                                |)
                              |) in
                            let~ char_len :=
                              M.alloc (|
                                BinOp.Wrap.sub (| M.read (| pre_len |), M.read (| len |) |)
                              |) in
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::str::pattern::MultiCharEq",
                                              C,
                                              [],
                                              "matches",
                                              []
                                            |),
                                            [
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::MultiCharEqSearcher",
                                                "char_eq"
                                              |);
                                              M.read (| c |)
                                            ]
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            Value.StructTuple
                                              "core::str::pattern::SearchStep::Match"
                                              [
                                                M.read (| i |);
                                                BinOp.Wrap.add (|
                                                  M.read (| i |),
                                                  M.read (| char_len |)
                                                |)
                                              ]
                                          |)
                                        |)
                                      |)
                                    |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            Value.StructTuple
                                              "core::str::pattern::SearchStep::Reject"
                                              [
                                                M.read (| i |);
                                                BinOp.Wrap.add (|
                                                  M.read (| i |),
                                                  M.read (| char_len |)
                                                |)
                                              ]
                                          |)
                                        |)
                                      |)
                                    |)))
                              ]
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  M.alloc (| Value.StructTuple "core::str::pattern::SearchStep::Done" [] |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (C : Ty.t),
        M.IsTraitInstance
          "core::str::pattern::ReverseSearcher"
          (Self C)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("next_back", InstanceField.Method (next_back C)) ].
    End Impl_core_str_pattern_ReverseSearcher_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqSearcher_C.
    
    Module Impl_core_str_pattern_DoubleEndedSearcher_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqSearcher_C.
      Definition Self (C : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ C ].
      
      Axiom Implements :
        forall (C : Ty.t),
        M.IsTraitInstance
          "core::str::pattern::DoubleEndedSearcher"
          (Self C)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_str_pattern_DoubleEndedSearcher_where_core_str_pattern_MultiCharEq_C_for_core_str_pattern_MultiCharEqSearcher_C.
    
    (* StructTuple
      {
        name := "CharArraySearcher";
        const_params := [ "N" ];
        ty_params := [];
        fields := [ Ty.associated ];
      } *)
    
    Module Impl_core_clone_Clone_for_core_str_pattern_CharArraySearcher_N.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArraySearcher") [ N ] [].
      
      (* Clone *)
      Definition clone (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructTuple
              "core::str::pattern::CharArraySearcher"
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::clone::Clone",
                    Ty.apply
                      (Ty.path "core::str::pattern::MultiCharEqSearcher")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                    [],
                    "clone",
                    []
                  |),
                  [
                    M.SubPointer.get_struct_tuple_field (|
                      M.read (| self |),
                      "core::str::pattern::CharArraySearcher",
                      0
                    |)
                  ]
                |)
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::clone::Clone"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method (clone N)) ].
    End Impl_core_clone_Clone_for_core_str_pattern_CharArraySearcher_N.
    
    Module Impl_core_fmt_Debug_for_core_str_pattern_CharArraySearcher_N.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArraySearcher") [ N ] [].
      
      (* Debug *)
      Definition fmt (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "core::fmt::Formatter",
                "debug_tuple_field1_finish",
                []
              |),
              [
                M.read (| f |);
                M.read (| Value.String "CharArraySearcher" |);
                M.alloc (|
                  M.SubPointer.get_struct_tuple_field (|
                    M.read (| self |),
                    "core::str::pattern::CharArraySearcher",
                    0
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::fmt::Debug"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method (fmt N)) ].
    End Impl_core_fmt_Debug_for_core_str_pattern_CharArraySearcher_N.
    
    (* StructTuple
      {
        name := "CharArrayRefSearcher";
        const_params := [ "N" ];
        ty_params := [];
        fields := [ Ty.associated ];
      } *)
    
    Module Impl_core_clone_Clone_for_core_str_pattern_CharArrayRefSearcher_N.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArrayRefSearcher") [ N ] [].
      
      (* Clone *)
      Definition clone (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructTuple
              "core::str::pattern::CharArrayRefSearcher"
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::clone::Clone",
                    Ty.apply
                      (Ty.path "core::str::pattern::MultiCharEqSearcher")
                      []
                      [
                        Ty.apply
                          (Ty.path "&")
                          []
                          [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                      ],
                    [],
                    "clone",
                    []
                  |),
                  [
                    M.SubPointer.get_struct_tuple_field (|
                      M.read (| self |),
                      "core::str::pattern::CharArrayRefSearcher",
                      0
                    |)
                  ]
                |)
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::clone::Clone"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method (clone N)) ].
    End Impl_core_clone_Clone_for_core_str_pattern_CharArrayRefSearcher_N.
    
    Module Impl_core_fmt_Debug_for_core_str_pattern_CharArrayRefSearcher_N.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArrayRefSearcher") [ N ] [].
      
      (* Debug *)
      Definition fmt (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "core::fmt::Formatter",
                "debug_tuple_field1_finish",
                []
              |),
              [
                M.read (| f |);
                M.read (| Value.String "CharArrayRefSearcher" |);
                M.alloc (|
                  M.SubPointer.get_struct_tuple_field (|
                    M.read (| self |),
                    "core::str::pattern::CharArrayRefSearcher",
                    0
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::fmt::Debug"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method (fmt N)) ].
    End Impl_core_fmt_Debug_for_core_str_pattern_CharArrayRefSearcher_N.
    
    Module Impl_core_str_pattern_Pattern_for_array_N_char.
      Definition Self (N : Value.t) : Ty.t := Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ].
      
      (*         type Searcher<$a> = $t; *)
      Definition _Searcher (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArraySearcher") [ N ] [].
      
      (*
              fn into_searcher<$a>(self, haystack: &$a str) -> $t {
                  ($smap)(($pmap)(self).into_searcher(haystack))
              }
      *)
      Definition into_searcher
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            Value.StructTuple
              "core::str::pattern::CharArraySearcher"
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::str::pattern::Pattern",
                    Ty.apply
                      (Ty.path "core::str::pattern::MultiCharEqPattern")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                    [],
                    "into_searcher",
                    []
                  |),
                  [
                    Value.StructTuple
                      "core::str::pattern::MultiCharEqPattern"
                      [ M.read (| self |) ];
                    M.read (| haystack |)
                  ]
                |)
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_contained_in<$a>(self, haystack: &$a str) -> bool {
                  ($pmap)(self).is_contained_in(haystack)
              }
      *)
      Definition is_contained_in
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "is_contained_in",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_prefix_of<$a>(self, haystack: &$a str) -> bool {
                  ($pmap)(self).is_prefix_of(haystack)
              }
      *)
      Definition is_prefix_of
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "is_prefix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn strip_prefix_of<$a>(self, haystack: &$a str) -> Option<&$a str> {
                  ($pmap)(self).strip_prefix_of(haystack)
              }
      *)
      Definition strip_prefix_of
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "strip_prefix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_suffix_of<$a>(self, haystack: &$a str) -> bool
              where
                  $t: ReverseSearcher<$a>,
              {
                  ($pmap)(self).is_suffix_of(haystack)
              }
      *)
      Definition is_suffix_of
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "is_suffix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn strip_suffix_of<$a>(self, haystack: &$a str) -> Option<&$a str>
              where
                  $t: ReverseSearcher<$a>,
              {
                  ($pmap)(self).strip_suffix_of(haystack)
              }
      *)
      Definition strip_suffix_of
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "strip_suffix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::str::pattern::Pattern"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Searcher", InstanceField.Ty (_Searcher N));
            ("into_searcher", InstanceField.Method (into_searcher N));
            ("is_contained_in", InstanceField.Method (is_contained_in N));
            ("is_prefix_of", InstanceField.Method (is_prefix_of N));
            ("strip_prefix_of", InstanceField.Method (strip_prefix_of N));
            ("is_suffix_of", InstanceField.Method (is_suffix_of N));
            ("strip_suffix_of", InstanceField.Method (strip_suffix_of N))
          ].
    End Impl_core_str_pattern_Pattern_for_array_N_char.
    
    Module Impl_core_str_pattern_Searcher_for_core_str_pattern_CharArraySearcher_N.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArraySearcher") [ N ] [].
      
      (*
              fn haystack(&self) -> &'a str {
                  self.0.haystack()
              }
      *)
      Definition haystack (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "haystack",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArraySearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next(&mut self) -> SearchStep {
                  self.0.next()
              }
      *)
      Definition next (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "next",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArraySearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_match(&mut self) -> Option<(usize, usize)> {
                  self.0.next_match()
              }
      *)
      Definition next_match
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "next_match",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArraySearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_reject(&mut self) -> Option<(usize, usize)> {
                  self.0.next_reject()
              }
      *)
      Definition next_reject
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "next_reject",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArraySearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::str::pattern::Searcher"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("haystack", InstanceField.Method (haystack N));
            ("next", InstanceField.Method (next N));
            ("next_match", InstanceField.Method (next_match N));
            ("next_reject", InstanceField.Method (next_reject N))
          ].
    End Impl_core_str_pattern_Searcher_for_core_str_pattern_CharArraySearcher_N.
    
    Module Impl_core_str_pattern_ReverseSearcher_for_core_str_pattern_CharArraySearcher_N.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArraySearcher") [ N ] [].
      
      (*
              fn next_back(&mut self) -> SearchStep {
                  self.0.next_back()
              }
      *)
      Definition next_back
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "next_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArraySearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_match_back(&mut self) -> Option<(usize, usize)> {
                  self.0.next_match_back()
              }
      *)
      Definition next_match_back
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "next_match_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArraySearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_reject_back(&mut self) -> Option<(usize, usize)> {
                  self.0.next_reject_back()
              }
      *)
      Definition next_reject_back
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ],
                [],
                "next_reject_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArraySearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::str::pattern::ReverseSearcher"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("next_back", InstanceField.Method (next_back N));
            ("next_match_back", InstanceField.Method (next_match_back N));
            ("next_reject_back", InstanceField.Method (next_reject_back N))
          ].
    End Impl_core_str_pattern_ReverseSearcher_for_core_str_pattern_CharArraySearcher_N.
    
    Module Impl_core_str_pattern_DoubleEndedSearcher_for_core_str_pattern_CharArraySearcher_N.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArraySearcher") [ N ] [].
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::str::pattern::DoubleEndedSearcher"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_str_pattern_DoubleEndedSearcher_for_core_str_pattern_CharArraySearcher_N.
    
    Module Impl_core_str_pattern_Pattern_for_ref__array_N_char.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ].
      
      (*         type Searcher<$a> = $t; *)
      Definition _Searcher (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArrayRefSearcher") [ N ] [].
      
      (*
              fn into_searcher<$a>(self, haystack: &$a str) -> $t {
                  ($smap)(($pmap)(self).into_searcher(haystack))
              }
      *)
      Definition into_searcher
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            Value.StructTuple
              "core::str::pattern::CharArrayRefSearcher"
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::str::pattern::Pattern",
                    Ty.apply
                      (Ty.path "core::str::pattern::MultiCharEqPattern")
                      []
                      [
                        Ty.apply
                          (Ty.path "&")
                          []
                          [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                      ],
                    [],
                    "into_searcher",
                    []
                  |),
                  [
                    Value.StructTuple
                      "core::str::pattern::MultiCharEqPattern"
                      [ M.read (| self |) ];
                    M.read (| haystack |)
                  ]
                |)
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_contained_in<$a>(self, haystack: &$a str) -> bool {
                  ($pmap)(self).is_contained_in(haystack)
              }
      *)
      Definition is_contained_in
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "is_contained_in",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_prefix_of<$a>(self, haystack: &$a str) -> bool {
                  ($pmap)(self).is_prefix_of(haystack)
              }
      *)
      Definition is_prefix_of
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "is_prefix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn strip_prefix_of<$a>(self, haystack: &$a str) -> Option<&$a str> {
                  ($pmap)(self).strip_prefix_of(haystack)
              }
      *)
      Definition strip_prefix_of
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "strip_prefix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_suffix_of<$a>(self, haystack: &$a str) -> bool
              where
                  $t: ReverseSearcher<$a>,
              {
                  ($pmap)(self).is_suffix_of(haystack)
              }
      *)
      Definition is_suffix_of
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "is_suffix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn strip_suffix_of<$a>(self, haystack: &$a str) -> Option<&$a str>
              where
                  $t: ReverseSearcher<$a>,
              {
                  ($pmap)(self).strip_suffix_of(haystack)
              }
      *)
      Definition strip_suffix_of
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "strip_suffix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::str::pattern::Pattern"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Searcher", InstanceField.Ty (_Searcher N));
            ("into_searcher", InstanceField.Method (into_searcher N));
            ("is_contained_in", InstanceField.Method (is_contained_in N));
            ("is_prefix_of", InstanceField.Method (is_prefix_of N));
            ("strip_prefix_of", InstanceField.Method (strip_prefix_of N));
            ("is_suffix_of", InstanceField.Method (is_suffix_of N));
            ("strip_suffix_of", InstanceField.Method (strip_suffix_of N))
          ].
    End Impl_core_str_pattern_Pattern_for_ref__array_N_char.
    
    Module Impl_core_str_pattern_Searcher_for_core_str_pattern_CharArrayRefSearcher_N.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArrayRefSearcher") [ N ] [].
      
      (*
              fn haystack(&self) -> &'a str {
                  self.0.haystack()
              }
      *)
      Definition haystack (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "haystack",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArrayRefSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next(&mut self) -> SearchStep {
                  self.0.next()
              }
      *)
      Definition next (N : Value.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "next",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArrayRefSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_match(&mut self) -> Option<(usize, usize)> {
                  self.0.next_match()
              }
      *)
      Definition next_match
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "next_match",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArrayRefSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_reject(&mut self) -> Option<(usize, usize)> {
                  self.0.next_reject()
              }
      *)
      Definition next_reject
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "next_reject",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArrayRefSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::str::pattern::Searcher"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("haystack", InstanceField.Method (haystack N));
            ("next", InstanceField.Method (next N));
            ("next_match", InstanceField.Method (next_match N));
            ("next_reject", InstanceField.Method (next_reject N))
          ].
    End Impl_core_str_pattern_Searcher_for_core_str_pattern_CharArrayRefSearcher_N.
    
    Module Impl_core_str_pattern_ReverseSearcher_for_core_str_pattern_CharArrayRefSearcher_N.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArrayRefSearcher") [ N ] [].
      
      (*
              fn next_back(&mut self) -> SearchStep {
                  self.0.next_back()
              }
      *)
      Definition next_back
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "next_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArrayRefSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_match_back(&mut self) -> Option<(usize, usize)> {
                  self.0.next_match_back()
              }
      *)
      Definition next_match_back
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "next_match_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArrayRefSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_reject_back(&mut self) -> Option<(usize, usize)> {
                  self.0.next_reject_back()
              }
      *)
      Definition next_reject_back
          (N : Value.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self N in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [
                    Ty.apply
                      (Ty.path "&")
                      []
                      [ Ty.apply (Ty.path "array") [ N ] [ Ty.path "char" ] ]
                  ],
                [],
                "next_reject_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharArrayRefSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::str::pattern::ReverseSearcher"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("next_back", InstanceField.Method (next_back N));
            ("next_match_back", InstanceField.Method (next_match_back N));
            ("next_reject_back", InstanceField.Method (next_reject_back N))
          ].
    End Impl_core_str_pattern_ReverseSearcher_for_core_str_pattern_CharArrayRefSearcher_N.
    
    Module Impl_core_str_pattern_DoubleEndedSearcher_for_core_str_pattern_CharArrayRefSearcher_N.
      Definition Self (N : Value.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharArrayRefSearcher") [ N ] [].
      
      Axiom Implements :
        forall (N : Value.t),
        M.IsTraitInstance
          "core::str::pattern::DoubleEndedSearcher"
          (Self N)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_str_pattern_DoubleEndedSearcher_for_core_str_pattern_CharArrayRefSearcher_N.
    
    (* StructTuple
      {
        name := "CharSliceSearcher";
        const_params := [];
        ty_params := [];
        fields := [ Ty.associated ];
      } *)
    
    Module Impl_core_clone_Clone_for_core_str_pattern_CharSliceSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSliceSearcher".
      
      (* Clone *)
      Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructTuple
              "core::str::pattern::CharSliceSearcher"
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::clone::Clone",
                    Ty.apply
                      (Ty.path "core::str::pattern::MultiCharEqSearcher")
                      []
                      [
                        Ty.apply
                          (Ty.path "&")
                          []
                          [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                      ],
                    [],
                    "clone",
                    []
                  |),
                  [
                    M.SubPointer.get_struct_tuple_field (|
                      M.read (| self |),
                      "core::str::pattern::CharSliceSearcher",
                      0
                    |)
                  ]
                |)
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::clone::Clone"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method clone) ].
    End Impl_core_clone_Clone_for_core_str_pattern_CharSliceSearcher.
    
    Module Impl_core_fmt_Debug_for_core_str_pattern_CharSliceSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSliceSearcher".
      
      (* Debug *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "core::fmt::Formatter",
                "debug_tuple_field1_finish",
                []
              |),
              [
                M.read (| f |);
                M.read (| Value.String "CharSliceSearcher" |);
                M.alloc (|
                  M.SubPointer.get_struct_tuple_field (|
                    M.read (| self |),
                    "core::str::pattern::CharSliceSearcher",
                    0
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Debug"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Debug_for_core_str_pattern_CharSliceSearcher.
    
    Module Impl_core_str_pattern_Searcher_for_core_str_pattern_CharSliceSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSliceSearcher".
      
      (*
              fn haystack(&self) -> &'a str {
                  self.0.haystack()
              }
      *)
      Definition haystack (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "haystack",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharSliceSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next(&mut self) -> SearchStep {
                  self.0.next()
              }
      *)
      Definition next (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "next",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharSliceSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_match(&mut self) -> Option<(usize, usize)> {
                  self.0.next_match()
              }
      *)
      Definition next_match (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "next_match",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharSliceSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_reject(&mut self) -> Option<(usize, usize)> {
                  self.0.next_reject()
              }
      *)
      Definition next_reject (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "next_reject",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharSliceSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::Searcher"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("haystack", InstanceField.Method haystack);
            ("next", InstanceField.Method next);
            ("next_match", InstanceField.Method next_match);
            ("next_reject", InstanceField.Method next_reject)
          ].
    End Impl_core_str_pattern_Searcher_for_core_str_pattern_CharSliceSearcher.
    
    Module Impl_core_str_pattern_ReverseSearcher_for_core_str_pattern_CharSliceSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSliceSearcher".
      
      (*
              fn next_back(&mut self) -> SearchStep {
                  self.0.next_back()
              }
      *)
      Definition next_back (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "next_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharSliceSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_match_back(&mut self) -> Option<(usize, usize)> {
                  self.0.next_match_back()
              }
      *)
      Definition next_match_back (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "next_match_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharSliceSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_reject_back(&mut self) -> Option<(usize, usize)> {
                  self.0.next_reject_back()
              }
      *)
      Definition next_reject_back (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqSearcher")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "next_reject_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharSliceSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::ReverseSearcher"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("next_back", InstanceField.Method next_back);
            ("next_match_back", InstanceField.Method next_match_back);
            ("next_reject_back", InstanceField.Method next_reject_back)
          ].
    End Impl_core_str_pattern_ReverseSearcher_for_core_str_pattern_CharSliceSearcher.
    
    Module Impl_core_str_pattern_DoubleEndedSearcher_for_core_str_pattern_CharSliceSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::CharSliceSearcher".
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::DoubleEndedSearcher"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_str_pattern_DoubleEndedSearcher_for_core_str_pattern_CharSliceSearcher.
    
    Module Impl_core_str_pattern_Pattern_for_ref__slice_char.
      Definition Self : Ty.t :=
        Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ].
      
      (*         type Searcher<$a> = $t; *)
      Definition _Searcher : Ty.t := Ty.path "core::str::pattern::CharSliceSearcher".
      
      (*
              fn into_searcher<$a>(self, haystack: &$a str) -> $t {
                  ($smap)(($pmap)(self).into_searcher(haystack))
              }
      *)
      Definition into_searcher (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            Value.StructTuple
              "core::str::pattern::CharSliceSearcher"
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::str::pattern::Pattern",
                    Ty.apply
                      (Ty.path "core::str::pattern::MultiCharEqPattern")
                      []
                      [
                        Ty.apply
                          (Ty.path "&")
                          []
                          [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                      ],
                    [],
                    "into_searcher",
                    []
                  |),
                  [
                    Value.StructTuple
                      "core::str::pattern::MultiCharEqPattern"
                      [ M.read (| self |) ];
                    M.read (| haystack |)
                  ]
                |)
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_contained_in<$a>(self, haystack: &$a str) -> bool {
                  ($pmap)(self).is_contained_in(haystack)
              }
      *)
      Definition is_contained_in (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "is_contained_in",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_prefix_of<$a>(self, haystack: &$a str) -> bool {
                  ($pmap)(self).is_prefix_of(haystack)
              }
      *)
      Definition is_prefix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "is_prefix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn strip_prefix_of<$a>(self, haystack: &$a str) -> Option<&$a str> {
                  ($pmap)(self).strip_prefix_of(haystack)
              }
      *)
      Definition strip_prefix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "strip_prefix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_suffix_of<$a>(self, haystack: &$a str) -> bool
              where
                  $t: ReverseSearcher<$a>,
              {
                  ($pmap)(self).is_suffix_of(haystack)
              }
      *)
      Definition is_suffix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "is_suffix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn strip_suffix_of<$a>(self, haystack: &$a str) -> Option<&$a str>
              where
                  $t: ReverseSearcher<$a>,
              {
                  ($pmap)(self).strip_suffix_of(haystack)
              }
      *)
      Definition strip_suffix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply
                  (Ty.path "core::str::pattern::MultiCharEqPattern")
                  []
                  [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "char" ] ]
                  ],
                [],
                "strip_suffix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::Pattern"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Searcher", InstanceField.Ty _Searcher);
            ("into_searcher", InstanceField.Method into_searcher);
            ("is_contained_in", InstanceField.Method is_contained_in);
            ("is_prefix_of", InstanceField.Method is_prefix_of);
            ("strip_prefix_of", InstanceField.Method strip_prefix_of);
            ("is_suffix_of", InstanceField.Method is_suffix_of);
            ("strip_suffix_of", InstanceField.Method strip_suffix_of)
          ].
    End Impl_core_str_pattern_Pattern_for_ref__slice_char.
    
    (* StructTuple
      {
        name := "CharPredicateSearcher";
        const_params := [];
        ty_params := [ "F" ];
        fields := [ Ty.associated ];
      } *)
    
    Module Impl_core_clone_Clone_where_core_clone_Clone_F_where_core_ops_function_FnMut_F_Tuple_char__for_core_str_pattern_CharPredicateSearcher_F.
      Definition Self (F : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharPredicateSearcher") [] [ F ].
      
      (* Clone *)
      Definition clone (F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructTuple
              "core::str::pattern::CharPredicateSearcher"
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::clone::Clone",
                    Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ F ],
                    [],
                    "clone",
                    []
                  |),
                  [
                    M.SubPointer.get_struct_tuple_field (|
                      M.read (| self |),
                      "core::str::pattern::CharPredicateSearcher",
                      0
                    |)
                  ]
                |)
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (F : Ty.t),
        M.IsTraitInstance
          "core::clone::Clone"
          (Self F)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method (clone F)) ].
    End Impl_core_clone_Clone_where_core_clone_Clone_F_where_core_ops_function_FnMut_F_Tuple_char__for_core_str_pattern_CharPredicateSearcher_F.
    
    Module Impl_core_fmt_Debug_where_core_ops_function_FnMut_F_Tuple_char__for_core_str_pattern_CharPredicateSearcher_F.
      Definition Self (F : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharPredicateSearcher") [] [ F ].
      
      (*
          fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
              f.debug_struct("CharPredicateSearcher")
                  .field("haystack", &self.0.haystack)
                  .field("char_indices", &self.0.char_indices)
                  .finish()
          }
      *)
      Definition fmt (F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "core::fmt::builders::DebugStruct",
                "finish",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "core::fmt::builders::DebugStruct",
                    "field",
                    []
                  |),
                  [
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "core::fmt::builders::DebugStruct",
                        "field",
                        []
                      |),
                      [
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::Formatter",
                              "debug_struct",
                              []
                            |),
                            [ M.read (| f |); M.read (| Value.String "CharPredicateSearcher" |) ]
                          |)
                        |);
                        M.read (| Value.String "haystack" |);
                        M.SubPointer.get_struct_record_field (|
                          M.SubPointer.get_struct_tuple_field (|
                            M.read (| self |),
                            "core::str::pattern::CharPredicateSearcher",
                            0
                          |),
                          "core::str::pattern::MultiCharEqSearcher",
                          "haystack"
                        |)
                      ]
                    |);
                    M.read (| Value.String "char_indices" |);
                    M.SubPointer.get_struct_record_field (|
                      M.SubPointer.get_struct_tuple_field (|
                        M.read (| self |),
                        "core::str::pattern::CharPredicateSearcher",
                        0
                      |),
                      "core::str::pattern::MultiCharEqSearcher",
                      "char_indices"
                    |)
                  ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (F : Ty.t),
        M.IsTraitInstance
          "core::fmt::Debug"
          (Self F)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method (fmt F)) ].
    End Impl_core_fmt_Debug_where_core_ops_function_FnMut_F_Tuple_char__for_core_str_pattern_CharPredicateSearcher_F.
    
    Module Impl_core_str_pattern_Searcher_where_core_ops_function_FnMut_F_Tuple_char__for_core_str_pattern_CharPredicateSearcher_F.
      Definition Self (F : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharPredicateSearcher") [] [ F ].
      
      (*
              fn haystack(&self) -> &'a str {
                  self.0.haystack()
              }
      *)
      Definition haystack (F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ F ],
                [],
                "haystack",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharPredicateSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next(&mut self) -> SearchStep {
                  self.0.next()
              }
      *)
      Definition next (F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ F ],
                [],
                "next",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharPredicateSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_match(&mut self) -> Option<(usize, usize)> {
                  self.0.next_match()
              }
      *)
      Definition next_match (F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ F ],
                [],
                "next_match",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharPredicateSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_reject(&mut self) -> Option<(usize, usize)> {
                  self.0.next_reject()
              }
      *)
      Definition next_reject (F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Searcher",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ F ],
                [],
                "next_reject",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharPredicateSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (F : Ty.t),
        M.IsTraitInstance
          "core::str::pattern::Searcher"
          (Self F)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("haystack", InstanceField.Method (haystack F));
            ("next", InstanceField.Method (next F));
            ("next_match", InstanceField.Method (next_match F));
            ("next_reject", InstanceField.Method (next_reject F))
          ].
    End Impl_core_str_pattern_Searcher_where_core_ops_function_FnMut_F_Tuple_char__for_core_str_pattern_CharPredicateSearcher_F.
    
    Module Impl_core_str_pattern_ReverseSearcher_where_core_ops_function_FnMut_F_Tuple_char__for_core_str_pattern_CharPredicateSearcher_F.
      Definition Self (F : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharPredicateSearcher") [] [ F ].
      
      (*
              fn next_back(&mut self) -> SearchStep {
                  self.0.next_back()
              }
      *)
      Definition next_back (F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ F ],
                [],
                "next_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharPredicateSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_match_back(&mut self) -> Option<(usize, usize)> {
                  self.0.next_match_back()
              }
      *)
      Definition next_match_back
          (F : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ F ],
                [],
                "next_match_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharPredicateSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn next_reject_back(&mut self) -> Option<(usize, usize)> {
                  self.0.next_reject_back()
              }
      *)
      Definition next_reject_back
          (F : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::ReverseSearcher",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqSearcher") [] [ F ],
                [],
                "next_reject_back",
                []
              |),
              [
                M.SubPointer.get_struct_tuple_field (|
                  M.read (| self |),
                  "core::str::pattern::CharPredicateSearcher",
                  0
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (F : Ty.t),
        M.IsTraitInstance
          "core::str::pattern::ReverseSearcher"
          (Self F)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("next_back", InstanceField.Method (next_back F));
            ("next_match_back", InstanceField.Method (next_match_back F));
            ("next_reject_back", InstanceField.Method (next_reject_back F))
          ].
    End Impl_core_str_pattern_ReverseSearcher_where_core_ops_function_FnMut_F_Tuple_char__for_core_str_pattern_CharPredicateSearcher_F.
    
    Module Impl_core_str_pattern_DoubleEndedSearcher_where_core_ops_function_FnMut_F_Tuple_char__for_core_str_pattern_CharPredicateSearcher_F.
      Definition Self (F : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharPredicateSearcher") [] [ F ].
      
      Axiom Implements :
        forall (F : Ty.t),
        M.IsTraitInstance
          "core::str::pattern::DoubleEndedSearcher"
          (Self F)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_str_pattern_DoubleEndedSearcher_where_core_ops_function_FnMut_F_Tuple_char__for_core_str_pattern_CharPredicateSearcher_F.
    
    Module Impl_core_str_pattern_Pattern_where_core_ops_function_FnMut_F_Tuple_char__for_F.
      Definition Self (F : Ty.t) : Ty.t := F.
      
      (*         type Searcher<$a> = $t; *)
      Definition _Searcher (F : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::str::pattern::CharPredicateSearcher") [] [ F ].
      
      (*
              fn into_searcher<$a>(self, haystack: &$a str) -> $t {
                  ($smap)(($pmap)(self).into_searcher(haystack))
              }
      *)
      Definition into_searcher
          (F : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            Value.StructTuple
              "core::str::pattern::CharPredicateSearcher"
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::str::pattern::Pattern",
                    Ty.apply (Ty.path "core::str::pattern::MultiCharEqPattern") [] [ F ],
                    [],
                    "into_searcher",
                    []
                  |),
                  [
                    Value.StructTuple
                      "core::str::pattern::MultiCharEqPattern"
                      [ M.read (| self |) ];
                    M.read (| haystack |)
                  ]
                |)
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_contained_in<$a>(self, haystack: &$a str) -> bool {
                  ($pmap)(self).is_contained_in(haystack)
              }
      *)
      Definition is_contained_in
          (F : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqPattern") [] [ F ],
                [],
                "is_contained_in",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_prefix_of<$a>(self, haystack: &$a str) -> bool {
                  ($pmap)(self).is_prefix_of(haystack)
              }
      *)
      Definition is_prefix_of
          (F : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqPattern") [] [ F ],
                [],
                "is_prefix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn strip_prefix_of<$a>(self, haystack: &$a str) -> Option<&$a str> {
                  ($pmap)(self).strip_prefix_of(haystack)
              }
      *)
      Definition strip_prefix_of
          (F : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqPattern") [] [ F ],
                [],
                "strip_prefix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_suffix_of<$a>(self, haystack: &$a str) -> bool
              where
                  $t: ReverseSearcher<$a>,
              {
                  ($pmap)(self).is_suffix_of(haystack)
              }
      *)
      Definition is_suffix_of
          (F : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqPattern") [] [ F ],
                [],
                "is_suffix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn strip_suffix_of<$a>(self, haystack: &$a str) -> Option<&$a str>
              where
                  $t: ReverseSearcher<$a>,
              {
                  ($pmap)(self).strip_suffix_of(haystack)
              }
      *)
      Definition strip_suffix_of
          (F : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self F in
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "core::str::pattern::MultiCharEqPattern") [] [ F ],
                [],
                "strip_suffix_of",
                []
              |),
              [
                Value.StructTuple "core::str::pattern::MultiCharEqPattern" [ M.read (| self |) ];
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (F : Ty.t),
        M.IsTraitInstance
          "core::str::pattern::Pattern"
          (Self F)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Searcher", InstanceField.Ty (_Searcher F));
            ("into_searcher", InstanceField.Method (into_searcher F));
            ("is_contained_in", InstanceField.Method (is_contained_in F));
            ("is_prefix_of", InstanceField.Method (is_prefix_of F));
            ("strip_prefix_of", InstanceField.Method (strip_prefix_of F));
            ("is_suffix_of", InstanceField.Method (is_suffix_of F));
            ("strip_suffix_of", InstanceField.Method (strip_suffix_of F))
          ].
    End Impl_core_str_pattern_Pattern_where_core_ops_function_FnMut_F_Tuple_char__for_F.
    
    Module Impl_core_str_pattern_Pattern_for_ref__ref__str.
      Definition Self : Ty.t :=
        Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ].
      
      (*         type Searcher<$a> = $t; *)
      Definition _Searcher : Ty.t := Ty.path "core::str::pattern::StrSearcher".
      
      (*
              fn into_searcher<$a>(self, haystack: &$a str) -> $t {
                  ($smap)(($pmap)(self).into_searcher(haystack))
              }
      *)
      Definition into_searcher (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::ops::function::Fn",
                Ty.function
                  [ Ty.tuple [ Ty.path "core::str::pattern::StrSearcher" ] ]
                  (Ty.path "core::str::pattern::StrSearcher"),
                [ Ty.tuple [ Ty.path "core::str::pattern::StrSearcher" ] ],
                "call",
                []
              |),
              [
                M.alloc (|
                  M.closure
                    (fun γ =>
                      ltac:(M.monadic
                        match γ with
                        | [ α0 ] =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| α0 |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let s := M.copy (| γ |) in
                                    M.read (| s |)))
                              ]
                            |)))
                        | _ => M.impossible "wrong number of arguments"
                        end))
                |);
                Value.Tuple
                  [
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::str::pattern::Pattern",
                        Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                        [],
                        "into_searcher",
                        []
                      |),
                      [
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::ops::function::Fn",
                            Ty.function
                              [
                                Ty.tuple
                                  [
                                    Ty.apply
                                      (Ty.path "&")
                                      []
                                      [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                                  ]
                              ]
                              (Ty.apply (Ty.path "&") [] [ Ty.path "str" ]),
                            [
                              Ty.tuple
                                [
                                  Ty.apply
                                    (Ty.path "&")
                                    []
                                    [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                                ]
                            ],
                            "call",
                            []
                          |),
                          [
                            M.alloc (|
                              M.closure
                                (fun γ =>
                                  ltac:(M.monadic
                                    match γ with
                                    | [ α0 ] =>
                                      ltac:(M.monadic
                                        (M.match_operator (|
                                          M.alloc (| α0 |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ := M.read (| γ |) in
                                                let s := M.copy (| γ |) in
                                                M.read (| s |)))
                                          ]
                                        |)))
                                    | _ => M.impossible "wrong number of arguments"
                                    end))
                            |);
                            Value.Tuple [ M.read (| self |) ]
                          ]
                        |);
                        M.read (| haystack |)
                      ]
                    |)
                  ]
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_contained_in<$a>(self, haystack: &$a str) -> bool {
                  ($pmap)(self).is_contained_in(haystack)
              }
      *)
      Definition is_contained_in (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                [],
                "is_contained_in",
                []
              |),
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::ops::function::Fn",
                    Ty.function
                      [
                        Ty.tuple
                          [
                            Ty.apply
                              (Ty.path "&")
                              []
                              [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                          ]
                      ]
                      (Ty.apply (Ty.path "&") [] [ Ty.path "str" ]),
                    [
                      Ty.tuple
                        [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                        ]
                    ],
                    "call",
                    []
                  |),
                  [
                    M.alloc (|
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ := M.read (| γ |) in
                                        let s := M.copy (| γ |) in
                                        M.read (| s |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |);
                    Value.Tuple [ M.read (| self |) ]
                  ]
                |);
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_prefix_of<$a>(self, haystack: &$a str) -> bool {
                  ($pmap)(self).is_prefix_of(haystack)
              }
      *)
      Definition is_prefix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                [],
                "is_prefix_of",
                []
              |),
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::ops::function::Fn",
                    Ty.function
                      [
                        Ty.tuple
                          [
                            Ty.apply
                              (Ty.path "&")
                              []
                              [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                          ]
                      ]
                      (Ty.apply (Ty.path "&") [] [ Ty.path "str" ]),
                    [
                      Ty.tuple
                        [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                        ]
                    ],
                    "call",
                    []
                  |),
                  [
                    M.alloc (|
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ := M.read (| γ |) in
                                        let s := M.copy (| γ |) in
                                        M.read (| s |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |);
                    Value.Tuple [ M.read (| self |) ]
                  ]
                |);
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn strip_prefix_of<$a>(self, haystack: &$a str) -> Option<&$a str> {
                  ($pmap)(self).strip_prefix_of(haystack)
              }
      *)
      Definition strip_prefix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                [],
                "strip_prefix_of",
                []
              |),
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::ops::function::Fn",
                    Ty.function
                      [
                        Ty.tuple
                          [
                            Ty.apply
                              (Ty.path "&")
                              []
                              [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                          ]
                      ]
                      (Ty.apply (Ty.path "&") [] [ Ty.path "str" ]),
                    [
                      Ty.tuple
                        [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                        ]
                    ],
                    "call",
                    []
                  |),
                  [
                    M.alloc (|
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ := M.read (| γ |) in
                                        let s := M.copy (| γ |) in
                                        M.read (| s |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |);
                    Value.Tuple [ M.read (| self |) ]
                  ]
                |);
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn is_suffix_of<$a>(self, haystack: &$a str) -> bool
              where
                  $t: ReverseSearcher<$a>,
              {
                  ($pmap)(self).is_suffix_of(haystack)
              }
      *)
      Definition is_suffix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                [],
                "is_suffix_of",
                []
              |),
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::ops::function::Fn",
                    Ty.function
                      [
                        Ty.tuple
                          [
                            Ty.apply
                              (Ty.path "&")
                              []
                              [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                          ]
                      ]
                      (Ty.apply (Ty.path "&") [] [ Ty.path "str" ]),
                    [
                      Ty.tuple
                        [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                        ]
                    ],
                    "call",
                    []
                  |),
                  [
                    M.alloc (|
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ := M.read (| γ |) in
                                        let s := M.copy (| γ |) in
                                        M.read (| s |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |);
                    Value.Tuple [ M.read (| self |) ]
                  ]
                |);
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
              fn strip_suffix_of<$a>(self, haystack: &$a str) -> Option<&$a str>
              where
                  $t: ReverseSearcher<$a>,
              {
                  ($pmap)(self).strip_suffix_of(haystack)
              }
      *)
      Definition strip_suffix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::str::pattern::Pattern",
                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                [],
                "strip_suffix_of",
                []
              |),
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::ops::function::Fn",
                    Ty.function
                      [
                        Ty.tuple
                          [
                            Ty.apply
                              (Ty.path "&")
                              []
                              [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                          ]
                      ]
                      (Ty.apply (Ty.path "&") [] [ Ty.path "str" ]),
                    [
                      Ty.tuple
                        [ Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                        ]
                    ],
                    "call",
                    []
                  |),
                  [
                    M.alloc (|
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ := M.read (| γ |) in
                                        let s := M.copy (| γ |) in
                                        M.read (| s |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |);
                    Value.Tuple [ M.read (| self |) ]
                  ]
                |);
                M.read (| haystack |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::Pattern"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Searcher", InstanceField.Ty _Searcher);
            ("into_searcher", InstanceField.Method into_searcher);
            ("is_contained_in", InstanceField.Method is_contained_in);
            ("is_prefix_of", InstanceField.Method is_prefix_of);
            ("strip_prefix_of", InstanceField.Method strip_prefix_of);
            ("is_suffix_of", InstanceField.Method is_suffix_of);
            ("strip_suffix_of", InstanceField.Method strip_suffix_of)
          ].
    End Impl_core_str_pattern_Pattern_for_ref__ref__str.
    
    Module Impl_core_str_pattern_Pattern_for_ref__str.
      Definition Self : Ty.t := Ty.apply (Ty.path "&") [] [ Ty.path "str" ].
      
      (*     type Searcher<'a> = StrSearcher<'a, 'b>; *)
      Definition _Searcher : Ty.t := Ty.path "core::str::pattern::StrSearcher".
      
      (*
          fn into_searcher(self, haystack: &str) -> StrSearcher<'_, 'b> {
              StrSearcher::new(haystack, self)
          }
      *)
      Definition into_searcher (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_associated_function (| Ty.path "core::str::pattern::StrSearcher", "new", [] |),
              [ M.read (| haystack |); M.read (| self |) ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn is_prefix_of(self, haystack: &str) -> bool {
              haystack.as_bytes().starts_with(self.as_bytes())
          }
      *)
      Definition is_prefix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                "starts_with",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                  [ M.read (| haystack |) ]
                |);
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                  [ M.read (| self |) ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn is_contained_in(self, haystack: &str) -> bool {
              if self.len() == 0 {
                  return true;
              }
      
              match self.len().cmp(&haystack.len()) {
                  Ordering::Less => {
                      if self.len() == 1 {
                          return haystack.as_bytes().contains(&self.as_bytes()[0]);
                      }
      
                      #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
                      if self.len() <= 32 {
                          if let Some(result) = simd_contains(self, haystack) {
                              return result;
                          }
                      }
      
                      self.into_searcher(haystack).next_match().is_some()
                  }
                  _ => self == haystack,
              }
          }
      *)
      Definition is_contained_in (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.call_closure (|
                                      M.get_associated_function (| Ty.path "str", "len", [] |),
                                      [ M.read (| self |) ]
                                    |),
                                    Value.Integer IntegerKind.Usize 0
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (| M.read (| M.return_ (| Value.Bool true |) |) |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (| "core::cmp::Ord", Ty.path "usize", [], "cmp", [] |),
                        [
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "len", [] |),
                              [ M.read (| self |) ]
                            |)
                          |);
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "len", [] |),
                              [ M.read (| haystack |) ]
                            |)
                          |)
                        ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let _ := M.is_struct_tuple (| γ, "core::cmp::Ordering::Less" |) in
                          let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "str",
                                                "len",
                                                []
                                              |),
                                              [ M.read (| self |) ]
                                            |),
                                            Value.Integer IntegerKind.Usize 1
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                                "contains",
                                                []
                                              |),
                                              [
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path "str",
                                                    "as_bytes",
                                                    []
                                                  |),
                                                  [ M.read (| haystack |) ]
                                                |);
                                                M.SubPointer.get_array_field (|
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.path "str",
                                                      "as_bytes",
                                                      []
                                                    |),
                                                    [ M.read (| self |) ]
                                                  |),
                                                  M.alloc (| Value.Integer IntegerKind.Usize 0 |)
                                                |)
                                              ]
                                            |)
                                          |)
                                        |)
                                      |)
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.le (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "str",
                                                "len",
                                                []
                                              |),
                                              [ M.read (| self |) ]
                                            |),
                                            Value.Integer IntegerKind.Usize 32
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_function (|
                                                    "core::str::pattern::simd_contains",
                                                    []
                                                  |),
                                                  [ M.read (| self |); M.read (| haystack |) ]
                                                |)
                                              |) in
                                            let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let result := M.copy (| γ0_0 |) in
                                            M.alloc (|
                                              M.never_to_any (|
                                                M.read (| M.return_ (| M.read (| result |) |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                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.tuple [ Ty.path "usize"; Ty.path "usize" ] ],
                                "is_some",
                                []
                              |),
                              [
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::str::pattern::Searcher",
                                      Ty.path "core::str::pattern::StrSearcher",
                                      [],
                                      "next_match",
                                      []
                                    |),
                                    [
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::str::pattern::Pattern",
                                            Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                                            [],
                                            "into_searcher",
                                            []
                                          |),
                                          [ M.read (| self |); M.read (| haystack |) ]
                                        |)
                                      |)
                                    ]
                                  |)
                                |)
                              ]
                            |)
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::cmp::PartialEq",
                                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                                [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ],
                                "eq",
                                []
                              |),
                              [ self; haystack ]
                            |)
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn strip_prefix_of(self, haystack: &str) -> Option<&str> {
              if self.is_prefix_of(haystack) {
                  // SAFETY: prefix was just verified to exist.
                  unsafe { Some(haystack.get_unchecked(self.as_bytes().len()..)) }
              } else {
                  None
              }
          }
      *)
      Definition strip_prefix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.read (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::str::pattern::Pattern",
                                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                                [],
                                "is_prefix_of",
                                []
                              |),
                              [ M.read (| self |); M.read (| haystack |) ]
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      M.alloc (|
                        Value.StructTuple
                          "core::option::Option::Some"
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "str",
                                "get_unchecked",
                                [
                                  Ty.apply
                                    (Ty.path "core::ops::range::RangeFrom")
                                    []
                                    [ Ty.path "usize" ]
                                ]
                              |),
                              [
                                M.read (| haystack |);
                                Value.StructRecord
                                  "core::ops::range::RangeFrom"
                                  [
                                    ("start",
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                          "len",
                                          []
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "str",
                                              "as_bytes",
                                              []
                                            |),
                                            [ M.read (| self |) ]
                                          |)
                                        ]
                                      |))
                                  ]
                              ]
                            |)
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn is_suffix_of<'a>(self, haystack: &'a str) -> bool
          where
              Self::Searcher<'a>: ReverseSearcher<'a>,
          {
              haystack.as_bytes().ends_with(self.as_bytes())
          }
      *)
      Definition is_suffix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                "ends_with",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                  [ M.read (| haystack |) ]
                |);
                M.call_closure (|
                  M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                  [ M.read (| self |) ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
          where
              Self::Searcher<'a>: ReverseSearcher<'a>,
          {
              if self.is_suffix_of(haystack) {
                  let i = haystack.len() - self.as_bytes().len();
                  // SAFETY: suffix was just verified to exist.
                  unsafe { Some(haystack.get_unchecked(..i)) }
              } else {
                  None
              }
          }
      *)
      Definition strip_suffix_of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; haystack ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            M.read (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::str::pattern::Pattern",
                                Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                                [],
                                "is_suffix_of",
                                []
                              |),
                              [ M.read (| self |); M.read (| haystack |) ]
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      let~ i :=
                        M.alloc (|
                          BinOp.Wrap.sub (|
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "len", [] |),
                              [ M.read (| haystack |) ]
                            |),
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                "len",
                                []
                              |),
                              [
                                M.call_closure (|
                                  M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                                  [ M.read (| self |) ]
                                |)
                              ]
                            |)
                          |)
                        |) in
                      M.alloc (|
                        Value.StructTuple
                          "core::option::Option::Some"
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "str",
                                "get_unchecked",
                                [
                                  Ty.apply
                                    (Ty.path "core::ops::range::RangeTo")
                                    []
                                    [ Ty.path "usize" ]
                                ]
                              |),
                              [
                                M.read (| haystack |);
                                Value.StructRecord
                                  "core::ops::range::RangeTo"
                                  [ ("end_", M.read (| i |)) ]
                              ]
                            |)
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::Pattern"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Searcher", InstanceField.Ty _Searcher);
            ("into_searcher", InstanceField.Method into_searcher);
            ("is_prefix_of", InstanceField.Method is_prefix_of);
            ("is_contained_in", InstanceField.Method is_contained_in);
            ("strip_prefix_of", InstanceField.Method strip_prefix_of);
            ("is_suffix_of", InstanceField.Method is_suffix_of);
            ("strip_suffix_of", InstanceField.Method strip_suffix_of)
          ].
    End Impl_core_str_pattern_Pattern_for_ref__str.
    
    (* StructRecord
      {
        name := "StrSearcher";
        const_params := [];
        ty_params := [];
        fields :=
          [
            ("haystack", Ty.apply (Ty.path "&") [] [ Ty.path "str" ]);
            ("needle", Ty.apply (Ty.path "&") [] [ Ty.path "str" ]);
            ("searcher", Ty.path "core::str::pattern::StrSearcherImpl")
          ];
      } *)
    
    Module Impl_core_clone_Clone_for_core_str_pattern_StrSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::StrSearcher".
      
      (* Clone *)
      Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructRecord
              "core::str::pattern::StrSearcher"
              [
                ("haystack",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::StrSearcher",
                        "haystack"
                      |)
                    ]
                  |));
                ("needle",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply (Ty.path "&") [] [ Ty.path "str" ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::StrSearcher",
                        "needle"
                      |)
                    ]
                  |));
                ("searcher",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.path "core::str::pattern::StrSearcherImpl",
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::StrSearcher",
                        "searcher"
                      |)
                    ]
                  |))
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::clone::Clone"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method clone) ].
    End Impl_core_clone_Clone_for_core_str_pattern_StrSearcher.
    
    Module Impl_core_fmt_Debug_for_core_str_pattern_StrSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::StrSearcher".
      
      (* Debug *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "core::fmt::Formatter",
                "debug_struct_field3_finish",
                []
              |),
              [
                M.read (| f |);
                M.read (| Value.String "StrSearcher" |);
                M.read (| Value.String "haystack" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::str::pattern::StrSearcher",
                  "haystack"
                |);
                M.read (| Value.String "needle" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::str::pattern::StrSearcher",
                  "needle"
                |);
                M.read (| Value.String "searcher" |);
                M.alloc (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::str::pattern::StrSearcher",
                    "searcher"
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Debug"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Debug_for_core_str_pattern_StrSearcher.
    
    (*
    Enum StrSearcherImpl
    {
      const_params := [];
      ty_params := [];
      variants :=
        [
          {
            name := "Empty";
            item := StructTuple [ Ty.path "core::str::pattern::EmptyNeedle" ];
            discriminant := None;
          };
          {
            name := "TwoWay";
            item := StructTuple [ Ty.path "core::str::pattern::TwoWaySearcher" ];
            discriminant := None;
          }
        ];
    }
    *)
    
    Module Impl_core_clone_Clone_for_core_str_pattern_StrSearcherImpl.
      Definition Self : Ty.t := Ty.path "core::str::pattern::StrSearcherImpl".
      
      (* Clone *)
      Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                self,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::StrSearcherImpl::Empty",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        Value.StructTuple
                          "core::str::pattern::StrSearcherImpl::Empty"
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::clone::Clone",
                                Ty.path "core::str::pattern::EmptyNeedle",
                                [],
                                "clone",
                                []
                              |),
                              [ M.read (| __self_0 |) ]
                            |)
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::StrSearcherImpl::TwoWay",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        Value.StructTuple
                          "core::str::pattern::StrSearcherImpl::TwoWay"
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::clone::Clone",
                                Ty.path "core::str::pattern::TwoWaySearcher",
                                [],
                                "clone",
                                []
                              |),
                              [ M.read (| __self_0 |) ]
                            |)
                          ]
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::clone::Clone"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method clone) ].
    End Impl_core_clone_Clone_for_core_str_pattern_StrSearcherImpl.
    
    Module Impl_core_fmt_Debug_for_core_str_pattern_StrSearcherImpl.
      Definition Self : Ty.t := Ty.path "core::str::pattern::StrSearcherImpl".
      
      (* Debug *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.read (|
              M.match_operator (|
                self,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::StrSearcherImpl::Empty",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "debug_tuple_field1_finish",
                            []
                          |),
                          [ M.read (| f |); M.read (| Value.String "Empty" |); __self_0 ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::str::pattern::StrSearcherImpl::TwoWay",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "debug_tuple_field1_finish",
                            []
                          |),
                          [ M.read (| f |); M.read (| Value.String "TwoWay" |); __self_0 ]
                        |)
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Debug"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Debug_for_core_str_pattern_StrSearcherImpl.
    
    (* StructRecord
      {
        name := "EmptyNeedle";
        const_params := [];
        ty_params := [];
        fields :=
          [
            ("position", Ty.path "usize");
            ("end_", Ty.path "usize");
            ("is_match_fw", Ty.path "bool");
            ("is_match_bw", Ty.path "bool");
            ("is_finished", Ty.path "bool")
          ];
      } *)
    
    Module Impl_core_clone_Clone_for_core_str_pattern_EmptyNeedle.
      Definition Self : Ty.t := Ty.path "core::str::pattern::EmptyNeedle".
      
      (* Clone *)
      Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructRecord
              "core::str::pattern::EmptyNeedle"
              [
                ("position",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::EmptyNeedle",
                        "position"
                      |)
                    ]
                  |));
                ("end_",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::EmptyNeedle",
                        "end"
                      |)
                    ]
                  |));
                ("is_match_fw",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "bool", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::EmptyNeedle",
                        "is_match_fw"
                      |)
                    ]
                  |));
                ("is_match_bw",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "bool", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::EmptyNeedle",
                        "is_match_bw"
                      |)
                    ]
                  |));
                ("is_finished",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "bool", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::EmptyNeedle",
                        "is_finished"
                      |)
                    ]
                  |))
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::clone::Clone"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method clone) ].
    End Impl_core_clone_Clone_for_core_str_pattern_EmptyNeedle.
    
    Module Impl_core_fmt_Debug_for_core_str_pattern_EmptyNeedle.
      Definition Self : Ty.t := Ty.path "core::str::pattern::EmptyNeedle".
      
      (* Debug *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "core::fmt::Formatter",
                "debug_struct_field5_finish",
                []
              |),
              [
                M.read (| f |);
                M.read (| Value.String "EmptyNeedle" |);
                M.read (| Value.String "position" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::str::pattern::EmptyNeedle",
                  "position"
                |);
                M.read (| Value.String "end" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::str::pattern::EmptyNeedle",
                  "end"
                |);
                M.read (| Value.String "is_match_fw" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::str::pattern::EmptyNeedle",
                  "is_match_fw"
                |);
                M.read (| Value.String "is_match_bw" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::str::pattern::EmptyNeedle",
                  "is_match_bw"
                |);
                M.read (| Value.String "is_finished" |);
                M.alloc (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::str::pattern::EmptyNeedle",
                    "is_finished"
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Debug"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Debug_for_core_str_pattern_EmptyNeedle.
    
    Module Impl_core_str_pattern_StrSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::StrSearcher".
      
      (*
          fn new(haystack: &'a str, needle: &'b str) -> StrSearcher<'a, 'b> {
              if needle.is_empty() {
                  StrSearcher {
                      haystack,
                      needle,
                      searcher: StrSearcherImpl::Empty(EmptyNeedle {
                          position: 0,
                          end: haystack.len(),
                          is_match_fw: true,
                          is_match_bw: true,
                          is_finished: false,
                      }),
                  }
              } else {
                  StrSearcher {
                      haystack,
                      needle,
                      searcher: StrSearcherImpl::TwoWay(TwoWaySearcher::new(
                          needle.as_bytes(),
                          haystack.len(),
                      )),
                  }
              }
          }
      *)
      Definition new (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ haystack; needle ] =>
          ltac:(M.monadic
            (let haystack := M.alloc (| haystack |) in
            let needle := M.alloc (| needle |) in
            M.read (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (| Ty.path "str", "is_empty", [] |),
                              [ M.read (| needle |) ]
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      M.alloc (|
                        Value.StructRecord
                          "core::str::pattern::StrSearcher"
                          [
                            ("haystack", M.read (| haystack |));
                            ("needle", M.read (| needle |));
                            ("searcher",
                              Value.StructTuple
                                "core::str::pattern::StrSearcherImpl::Empty"
                                [
                                  Value.StructRecord
                                    "core::str::pattern::EmptyNeedle"
                                    [
                                      ("position", Value.Integer IntegerKind.Usize 0);
                                      ("end_",
                                        M.call_closure (|
                                          M.get_associated_function (| Ty.path "str", "len", [] |),
                                          [ M.read (| haystack |) ]
                                        |));
                                      ("is_match_fw", Value.Bool true);
                                      ("is_match_bw", Value.Bool true);
                                      ("is_finished", Value.Bool false)
                                    ]
                                ])
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (|
                        Value.StructRecord
                          "core::str::pattern::StrSearcher"
                          [
                            ("haystack", M.read (| haystack |));
                            ("needle", M.read (| needle |));
                            ("searcher",
                              Value.StructTuple
                                "core::str::pattern::StrSearcherImpl::TwoWay"
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "core::str::pattern::TwoWaySearcher",
                                      "new",
                                      []
                                    |),
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "str",
                                          "as_bytes",
                                          []
                                        |),
                                        [ M.read (| needle |) ]
                                      |);
                                      M.call_closure (|
                                        M.get_associated_function (| Ty.path "str", "len", [] |),
                                        [ M.read (| haystack |) ]
                                      |)
                                    ]
                                  |)
                                ])
                          ]
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_new : M.IsAssociatedFunction Self "new" new.
    End Impl_core_str_pattern_StrSearcher.
    
    Module Impl_core_str_pattern_Searcher_for_core_str_pattern_StrSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::StrSearcher".
      
      (*
          fn haystack(&self) -> &'a str {
              self.haystack
          }
      *)
      Definition haystack (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.SubPointer.get_struct_record_field (|
                M.read (| self |),
                "core::str::pattern::StrSearcher",
                "haystack"
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn next(&mut self) -> SearchStep {
              match self.searcher {
                  StrSearcherImpl::Empty(ref mut searcher) => {
                      if searcher.is_finished {
                          return SearchStep::Done;
                      }
                      // empty needle rejects every char and matches every empty string between them
                      let is_match = searcher.is_match_fw;
                      searcher.is_match_fw = !searcher.is_match_fw;
                      let pos = searcher.position;
                      match self.haystack[pos..].chars().next() {
                          _ if is_match => SearchStep::Match(pos, pos),
                          None => {
                              searcher.is_finished = true;
                              SearchStep::Done
                          }
                          Some(ch) => {
                              searcher.position += ch.len_utf8();
                              SearchStep::Reject(pos, searcher.position)
                          }
                      }
                  }
                  StrSearcherImpl::TwoWay(ref mut searcher) => {
                      // TwoWaySearcher produces valid *Match* indices that split at char boundaries
                      // as long as it does correct matching and that haystack and needle are
                      // valid UTF-8
                      // *Rejects* from the algorithm can fall on any indices, but we will walk them
                      // manually to the next character boundary, so that they are utf-8 safe.
                      if searcher.position == self.haystack.len() {
                          return SearchStep::Done;
                      }
                      let is_long = searcher.memory == usize::MAX;
                      match searcher.next::<RejectAndMatch>(
                          self.haystack.as_bytes(),
                          self.needle.as_bytes(),
                          is_long,
                      ) {
                          SearchStep::Reject(a, mut b) => {
                              // skip to next char boundary
                              while !self.haystack.is_char_boundary(b) {
                                  b += 1;
                              }
                              searcher.position = cmp::max(b, searcher.position);
                              SearchStep::Reject(a, b)
                          }
                          otherwise => otherwise,
                      }
                  }
              }
          }
      *)
      Definition next (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  M.match_operator (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "core::str::pattern::StrSearcher",
                      "searcher"
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::str::pattern::StrSearcherImpl::Empty",
                              0
                            |) in
                          let searcher := M.alloc (| γ0_0 |) in
                          let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.SubPointer.get_struct_record_field (|
                                          M.read (| searcher |),
                                          "core::str::pattern::EmptyNeedle",
                                          "is_finished"
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            Value.StructTuple
                                              "core::str::pattern::SearchStep::Done"
                                              []
                                          |)
                                        |)
                                      |)
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ is_match :=
                            M.copy (|
                              M.SubPointer.get_struct_record_field (|
                                M.read (| searcher |),
                                "core::str::pattern::EmptyNeedle",
                                "is_match_fw"
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              M.SubPointer.get_struct_record_field (|
                                M.read (| searcher |),
                                "core::str::pattern::EmptyNeedle",
                                "is_match_fw"
                              |),
                              UnOp.not (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| searcher |),
                                    "core::str::pattern::EmptyNeedle",
                                    "is_match_fw"
                                  |)
                                |)
                              |)
                            |) in
                          let~ pos :=
                            M.copy (|
                              M.SubPointer.get_struct_record_field (|
                                M.read (| searcher |),
                                "core::str::pattern::EmptyNeedle",
                                "position"
                              |)
                            |) in
                          M.match_operator (|
                            M.alloc (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::iterator::Iterator",
                                  Ty.path "core::str::iter::Chars",
                                  [],
                                  "next",
                                  []
                                |),
                                [
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (| Ty.path "str", "chars", [] |),
                                      [
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::ops::index::Index",
                                            Ty.path "str",
                                            [
                                              Ty.apply
                                                (Ty.path "core::ops::range::RangeFrom")
                                                []
                                                [ Ty.path "usize" ]
                                            ],
                                            "index",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::StrSearcher",
                                                "haystack"
                                              |)
                                            |);
                                            Value.StructRecord
                                              "core::ops::range::RangeFrom"
                                              [ ("start", M.read (| pos |)) ]
                                          ]
                                        |)
                                      ]
                                    |)
                                  |)
                                ]
                              |)
                            |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ := is_match in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  M.alloc (|
                                    Value.StructTuple
                                      "core::str::pattern::SearchStep::Match"
                                      [ M.read (| pos |); M.read (| pos |) ]
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                  let~ _ :=
                                    M.write (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| searcher |),
                                        "core::str::pattern::EmptyNeedle",
                                        "is_finished"
                                      |),
                                      Value.Bool true
                                    |) in
                                  M.alloc (|
                                    Value.StructTuple "core::str::pattern::SearchStep::Done" []
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ0_0 :=
                                    M.SubPointer.get_struct_tuple_field (|
                                      γ,
                                      "core::option::Option::Some",
                                      0
                                    |) in
                                  let ch := M.copy (| γ0_0 |) in
                                  let~ _ :=
                                    let β :=
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| searcher |),
                                        "core::str::pattern::EmptyNeedle",
                                        "position"
                                      |) in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.add (|
                                        M.read (| β |),
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "char",
                                            "len_utf8",
                                            []
                                          |),
                                          [ M.read (| ch |) ]
                                        |)
                                      |)
                                    |) in
                                  M.alloc (|
                                    Value.StructTuple
                                      "core::str::pattern::SearchStep::Reject"
                                      [
                                        M.read (| pos |);
                                        M.read (|
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| searcher |),
                                            "core::str::pattern::EmptyNeedle",
                                            "position"
                                          |)
                                        |)
                                      ]
                                  |)))
                            ]
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::str::pattern::StrSearcherImpl::TwoWay",
                              0
                            |) in
                          let searcher := M.alloc (| γ0_0 |) in
                          let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| searcher |),
                                                "core::str::pattern::TwoWaySearcher",
                                                "position"
                                              |)
                                            |),
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "str",
                                                "len",
                                                []
                                              |),
                                              [
                                                M.read (|
                                                  M.SubPointer.get_struct_record_field (|
                                                    M.read (| self |),
                                                    "core::str::pattern::StrSearcher",
                                                    "haystack"
                                                  |)
                                                |)
                                              ]
                                            |)
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            Value.StructTuple
                                              "core::str::pattern::SearchStep::Done"
                                              []
                                          |)
                                        |)
                                      |)
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ is_long :=
                            M.alloc (|
                              BinOp.eq (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| searcher |),
                                    "core::str::pattern::TwoWaySearcher",
                                    "memory"
                                  |)
                                |),
                                M.read (| M.get_constant (| "core::num::MAX" |) |)
                              |)
                            |) in
                          M.match_operator (|
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "core::str::pattern::TwoWaySearcher",
                                  "next",
                                  [ Ty.path "core::str::pattern::RejectAndMatch" ]
                                |),
                                [
                                  M.read (| searcher |);
                                  M.call_closure (|
                                    M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                                    [
                                      M.read (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::StrSearcher",
                                          "haystack"
                                        |)
                                      |)
                                    ]
                                  |);
                                  M.call_closure (|
                                    M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                                    [
                                      M.read (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::StrSearcher",
                                          "needle"
                                        |)
                                      |)
                                    ]
                                  |);
                                  M.read (| is_long |)
                                ]
                              |)
                            |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ0_0 :=
                                    M.SubPointer.get_struct_tuple_field (|
                                      γ,
                                      "core::str::pattern::SearchStep::Reject",
                                      0
                                    |) in
                                  let γ0_1 :=
                                    M.SubPointer.get_struct_tuple_field (|
                                      γ,
                                      "core::str::pattern::SearchStep::Reject",
                                      1
                                    |) in
                                  let a := M.copy (| γ0_0 |) in
                                  let b := M.copy (| γ0_1 |) in
                                  let~ _ :=
                                    M.loop (|
                                      ltac:(M.monadic
                                        (M.match_operator (|
                                          M.alloc (| Value.Tuple [] |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ :=
                                                  M.use
                                                    (M.alloc (|
                                                      UnOp.not (|
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path "str",
                                                            "is_char_boundary",
                                                            []
                                                          |),
                                                          [
                                                            M.read (|
                                                              M.SubPointer.get_struct_record_field (|
                                                                M.read (| self |),
                                                                "core::str::pattern::StrSearcher",
                                                                "haystack"
                                                              |)
                                                            |);
                                                            M.read (| b |)
                                                          ]
                                                        |)
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  let β := b in
                                                  M.write (|
                                                    β,
                                                    BinOp.Wrap.add (|
                                                      M.read (| β |),
                                                      Value.Integer IntegerKind.Usize 1
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ =>
                                              ltac:(M.monadic
                                                (M.alloc (|
                                                  M.never_to_any (|
                                                    M.read (|
                                                      let~ _ :=
                                                        M.alloc (|
                                                          M.never_to_any (|
                                                            M.read (| M.break (||) |)
                                                          |)
                                                        |) in
                                                      M.alloc (| Value.Tuple [] |)
                                                    |)
                                                  |)
                                                |)))
                                          ]
                                        |)))
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| searcher |),
                                        "core::str::pattern::TwoWaySearcher",
                                        "position"
                                      |),
                                      M.call_closure (|
                                        M.get_function (| "core::cmp::max", [ Ty.path "usize" ] |),
                                        [
                                          M.read (| b |);
                                          M.read (|
                                            M.SubPointer.get_struct_record_field (|
                                              M.read (| searcher |),
                                              "core::str::pattern::TwoWaySearcher",
                                              "position"
                                            |)
                                          |)
                                        ]
                                      |)
                                    |) in
                                  M.alloc (|
                                    Value.StructTuple
                                      "core::str::pattern::SearchStep::Reject"
                                      [ M.read (| a |); M.read (| b |) ]
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let otherwise := M.copy (| γ |) in
                                  otherwise))
                            ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn next_match(&mut self) -> Option<(usize, usize)> {
              match self.searcher {
                  StrSearcherImpl::Empty(..) => loop {
                      match self.next() {
                          SearchStep::Match(a, b) => return Some((a, b)),
                          SearchStep::Done => return None,
                          SearchStep::Reject(..) => {}
                      }
                  },
                  StrSearcherImpl::TwoWay(ref mut searcher) => {
                      let is_long = searcher.memory == usize::MAX;
                      // write out `true` and `false` cases to encourage the compiler
                      // to specialize the two cases separately.
                      if is_long {
                          searcher.next::<MatchOnly>(
                              self.haystack.as_bytes(),
                              self.needle.as_bytes(),
                              true,
                          )
                      } else {
                          searcher.next::<MatchOnly>(
                              self.haystack.as_bytes(),
                              self.needle.as_bytes(),
                              false,
                          )
                      }
                  }
              }
          }
      *)
      Definition next_match (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  M.match_operator (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "core::str::pattern::StrSearcher",
                      "searcher"
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let _ :=
                            M.is_struct_tuple (|
                              γ,
                              "core::str::pattern::StrSearcherImpl::Empty"
                            |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.loop (|
                                  ltac:(M.monadic
                                    (M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::str::pattern::Searcher",
                                            Ty.path "core::str::pattern::StrSearcher",
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ M.read (| self |) ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::str::pattern::SearchStep::Match",
                                                0
                                              |) in
                                            let γ0_1 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::str::pattern::SearchStep::Match",
                                                1
                                              |) in
                                            let a := M.copy (| γ0_0 |) in
                                            let b := M.copy (| γ0_1 |) in
                                            M.alloc (|
                                              M.never_to_any (|
                                                M.read (|
                                                  M.return_ (|
                                                    Value.StructTuple
                                                      "core::option::Option::Some"
                                                      [
                                                        Value.Tuple
                                                          [ M.read (| a |); M.read (| b |) ]
                                                      ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_struct_tuple (|
                                                γ,
                                                "core::str::pattern::SearchStep::Done"
                                              |) in
                                            M.alloc (|
                                              M.never_to_any (|
                                                M.read (|
                                                  M.return_ (|
                                                    Value.StructTuple
                                                      "core::option::Option::None"
                                                      []
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_struct_tuple (|
                                                γ,
                                                "core::str::pattern::SearchStep::Reject"
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)))
                                |)
                              |)
                            |)
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::str::pattern::StrSearcherImpl::TwoWay",
                              0
                            |) in
                          let searcher := M.alloc (| γ0_0 |) in
                          let~ is_long :=
                            M.alloc (|
                              BinOp.eq (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| searcher |),
                                    "core::str::pattern::TwoWaySearcher",
                                    "memory"
                                  |)
                                |),
                                M.read (| M.get_constant (| "core::num::MAX" |) |)
                              |)
                            |) in
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ := M.use is_long in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "core::str::pattern::TwoWaySearcher",
                                        "next",
                                        [ Ty.path "core::str::pattern::MatchOnly" ]
                                      |),
                                      [
                                        M.read (| searcher |);
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "str",
                                            "as_bytes",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::StrSearcher",
                                                "haystack"
                                              |)
                                            |)
                                          ]
                                        |);
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "str",
                                            "as_bytes",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::StrSearcher",
                                                "needle"
                                              |)
                                            |)
                                          ]
                                        |);
                                        Value.Bool true
                                      ]
                                    |)
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "core::str::pattern::TwoWaySearcher",
                                        "next",
                                        [ Ty.path "core::str::pattern::MatchOnly" ]
                                      |),
                                      [
                                        M.read (| searcher |);
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "str",
                                            "as_bytes",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::StrSearcher",
                                                "haystack"
                                              |)
                                            |)
                                          ]
                                        |);
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "str",
                                            "as_bytes",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::StrSearcher",
                                                "needle"
                                              |)
                                            |)
                                          ]
                                        |);
                                        Value.Bool false
                                      ]
                                    |)
                                  |)))
                            ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::Searcher"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("haystack", InstanceField.Method haystack);
            ("next", InstanceField.Method next);
            ("next_match", InstanceField.Method next_match)
          ].
    End Impl_core_str_pattern_Searcher_for_core_str_pattern_StrSearcher.
    
    Module Impl_core_str_pattern_ReverseSearcher_for_core_str_pattern_StrSearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::StrSearcher".
      
      (*
          fn next_back(&mut self) -> SearchStep {
              match self.searcher {
                  StrSearcherImpl::Empty(ref mut searcher) => {
                      if searcher.is_finished {
                          return SearchStep::Done;
                      }
                      let is_match = searcher.is_match_bw;
                      searcher.is_match_bw = !searcher.is_match_bw;
                      let end = searcher.end;
                      match self.haystack[..end].chars().next_back() {
                          _ if is_match => SearchStep::Match(end, end),
                          None => {
                              searcher.is_finished = true;
                              SearchStep::Done
                          }
                          Some(ch) => {
                              searcher.end -= ch.len_utf8();
                              SearchStep::Reject(searcher.end, end)
                          }
                      }
                  }
                  StrSearcherImpl::TwoWay(ref mut searcher) => {
                      if searcher.end == 0 {
                          return SearchStep::Done;
                      }
                      let is_long = searcher.memory == usize::MAX;
                      match searcher.next_back::<RejectAndMatch>(
                          self.haystack.as_bytes(),
                          self.needle.as_bytes(),
                          is_long,
                      ) {
                          SearchStep::Reject(mut a, b) => {
                              // skip to next char boundary
                              while !self.haystack.is_char_boundary(a) {
                                  a -= 1;
                              }
                              searcher.end = cmp::min(a, searcher.end);
                              SearchStep::Reject(a, b)
                          }
                          otherwise => otherwise,
                      }
                  }
              }
          }
      *)
      Definition next_back (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  M.match_operator (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "core::str::pattern::StrSearcher",
                      "searcher"
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::str::pattern::StrSearcherImpl::Empty",
                              0
                            |) in
                          let searcher := M.alloc (| γ0_0 |) in
                          let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.SubPointer.get_struct_record_field (|
                                          M.read (| searcher |),
                                          "core::str::pattern::EmptyNeedle",
                                          "is_finished"
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            Value.StructTuple
                                              "core::str::pattern::SearchStep::Done"
                                              []
                                          |)
                                        |)
                                      |)
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ is_match :=
                            M.copy (|
                              M.SubPointer.get_struct_record_field (|
                                M.read (| searcher |),
                                "core::str::pattern::EmptyNeedle",
                                "is_match_bw"
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              M.SubPointer.get_struct_record_field (|
                                M.read (| searcher |),
                                "core::str::pattern::EmptyNeedle",
                                "is_match_bw"
                              |),
                              UnOp.not (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| searcher |),
                                    "core::str::pattern::EmptyNeedle",
                                    "is_match_bw"
                                  |)
                                |)
                              |)
                            |) in
                          let~ end_ :=
                            M.copy (|
                              M.SubPointer.get_struct_record_field (|
                                M.read (| searcher |),
                                "core::str::pattern::EmptyNeedle",
                                "end"
                              |)
                            |) in
                          M.match_operator (|
                            M.alloc (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::double_ended::DoubleEndedIterator",
                                  Ty.path "core::str::iter::Chars",
                                  [],
                                  "next_back",
                                  []
                                |),
                                [
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (| Ty.path "str", "chars", [] |),
                                      [
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::ops::index::Index",
                                            Ty.path "str",
                                            [
                                              Ty.apply
                                                (Ty.path "core::ops::range::RangeTo")
                                                []
                                                [ Ty.path "usize" ]
                                            ],
                                            "index",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::StrSearcher",
                                                "haystack"
                                              |)
                                            |);
                                            Value.StructRecord
                                              "core::ops::range::RangeTo"
                                              [ ("end_", M.read (| end_ |)) ]
                                          ]
                                        |)
                                      ]
                                    |)
                                  |)
                                ]
                              |)
                            |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ := is_match in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  M.alloc (|
                                    Value.StructTuple
                                      "core::str::pattern::SearchStep::Match"
                                      [ M.read (| end_ |); M.read (| end_ |) ]
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let _ :=
                                    M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                  let~ _ :=
                                    M.write (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| searcher |),
                                        "core::str::pattern::EmptyNeedle",
                                        "is_finished"
                                      |),
                                      Value.Bool true
                                    |) in
                                  M.alloc (|
                                    Value.StructTuple "core::str::pattern::SearchStep::Done" []
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ0_0 :=
                                    M.SubPointer.get_struct_tuple_field (|
                                      γ,
                                      "core::option::Option::Some",
                                      0
                                    |) in
                                  let ch := M.copy (| γ0_0 |) in
                                  let~ _ :=
                                    let β :=
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| searcher |),
                                        "core::str::pattern::EmptyNeedle",
                                        "end"
                                      |) in
                                    M.write (|
                                      β,
                                      BinOp.Wrap.sub (|
                                        M.read (| β |),
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "char",
                                            "len_utf8",
                                            []
                                          |),
                                          [ M.read (| ch |) ]
                                        |)
                                      |)
                                    |) in
                                  M.alloc (|
                                    Value.StructTuple
                                      "core::str::pattern::SearchStep::Reject"
                                      [
                                        M.read (|
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| searcher |),
                                            "core::str::pattern::EmptyNeedle",
                                            "end"
                                          |)
                                        |);
                                        M.read (| end_ |)
                                      ]
                                  |)))
                            ]
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::str::pattern::StrSearcherImpl::TwoWay",
                              0
                            |) in
                          let searcher := M.alloc (| γ0_0 |) in
                          let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| searcher |),
                                                "core::str::pattern::TwoWaySearcher",
                                                "end"
                                              |)
                                            |),
                                            Value.Integer IntegerKind.Usize 0
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            Value.StructTuple
                                              "core::str::pattern::SearchStep::Done"
                                              []
                                          |)
                                        |)
                                      |)
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ is_long :=
                            M.alloc (|
                              BinOp.eq (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| searcher |),
                                    "core::str::pattern::TwoWaySearcher",
                                    "memory"
                                  |)
                                |),
                                M.read (| M.get_constant (| "core::num::MAX" |) |)
                              |)
                            |) in
                          M.match_operator (|
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "core::str::pattern::TwoWaySearcher",
                                  "next_back",
                                  [ Ty.path "core::str::pattern::RejectAndMatch" ]
                                |),
                                [
                                  M.read (| searcher |);
                                  M.call_closure (|
                                    M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                                    [
                                      M.read (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::StrSearcher",
                                          "haystack"
                                        |)
                                      |)
                                    ]
                                  |);
                                  M.call_closure (|
                                    M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                                    [
                                      M.read (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::StrSearcher",
                                          "needle"
                                        |)
                                      |)
                                    ]
                                  |);
                                  M.read (| is_long |)
                                ]
                              |)
                            |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ0_0 :=
                                    M.SubPointer.get_struct_tuple_field (|
                                      γ,
                                      "core::str::pattern::SearchStep::Reject",
                                      0
                                    |) in
                                  let γ0_1 :=
                                    M.SubPointer.get_struct_tuple_field (|
                                      γ,
                                      "core::str::pattern::SearchStep::Reject",
                                      1
                                    |) in
                                  let a := M.copy (| γ0_0 |) in
                                  let b := M.copy (| γ0_1 |) in
                                  let~ _ :=
                                    M.loop (|
                                      ltac:(M.monadic
                                        (M.match_operator (|
                                          M.alloc (| Value.Tuple [] |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ :=
                                                  M.use
                                                    (M.alloc (|
                                                      UnOp.not (|
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path "str",
                                                            "is_char_boundary",
                                                            []
                                                          |),
                                                          [
                                                            M.read (|
                                                              M.SubPointer.get_struct_record_field (|
                                                                M.read (| self |),
                                                                "core::str::pattern::StrSearcher",
                                                                "haystack"
                                                              |)
                                                            |);
                                                            M.read (| a |)
                                                          ]
                                                        |)
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ _ :=
                                                  let β := a in
                                                  M.write (|
                                                    β,
                                                    BinOp.Wrap.sub (|
                                                      M.read (| β |),
                                                      Value.Integer IntegerKind.Usize 1
                                                    |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)));
                                            fun γ =>
                                              ltac:(M.monadic
                                                (M.alloc (|
                                                  M.never_to_any (|
                                                    M.read (|
                                                      let~ _ :=
                                                        M.alloc (|
                                                          M.never_to_any (|
                                                            M.read (| M.break (||) |)
                                                          |)
                                                        |) in
                                                      M.alloc (| Value.Tuple [] |)
                                                    |)
                                                  |)
                                                |)))
                                          ]
                                        |)))
                                    |) in
                                  let~ _ :=
                                    M.write (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| searcher |),
                                        "core::str::pattern::TwoWaySearcher",
                                        "end"
                                      |),
                                      M.call_closure (|
                                        M.get_function (| "core::cmp::min", [ Ty.path "usize" ] |),
                                        [
                                          M.read (| a |);
                                          M.read (|
                                            M.SubPointer.get_struct_record_field (|
                                              M.read (| searcher |),
                                              "core::str::pattern::TwoWaySearcher",
                                              "end"
                                            |)
                                          |)
                                        ]
                                      |)
                                    |) in
                                  M.alloc (|
                                    Value.StructTuple
                                      "core::str::pattern::SearchStep::Reject"
                                      [ M.read (| a |); M.read (| b |) ]
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (let otherwise := M.copy (| γ |) in
                                  otherwise))
                            ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn next_match_back(&mut self) -> Option<(usize, usize)> {
              match self.searcher {
                  StrSearcherImpl::Empty(..) => loop {
                      match self.next_back() {
                          SearchStep::Match(a, b) => return Some((a, b)),
                          SearchStep::Done => return None,
                          SearchStep::Reject(..) => {}
                      }
                  },
                  StrSearcherImpl::TwoWay(ref mut searcher) => {
                      let is_long = searcher.memory == usize::MAX;
                      // write out `true` and `false`, like `next_match`
                      if is_long {
                          searcher.next_back::<MatchOnly>(
                              self.haystack.as_bytes(),
                              self.needle.as_bytes(),
                              true,
                          )
                      } else {
                          searcher.next_back::<MatchOnly>(
                              self.haystack.as_bytes(),
                              self.needle.as_bytes(),
                              false,
                          )
                      }
                  }
              }
          }
      *)
      Definition next_match_back (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  M.match_operator (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "core::str::pattern::StrSearcher",
                      "searcher"
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let _ :=
                            M.is_struct_tuple (|
                              γ,
                              "core::str::pattern::StrSearcherImpl::Empty"
                            |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.loop (|
                                  ltac:(M.monadic
                                    (M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::str::pattern::ReverseSearcher",
                                            Ty.path "core::str::pattern::StrSearcher",
                                            [],
                                            "next_back",
                                            []
                                          |),
                                          [ M.read (| self |) ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::str::pattern::SearchStep::Match",
                                                0
                                              |) in
                                            let γ0_1 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::str::pattern::SearchStep::Match",
                                                1
                                              |) in
                                            let a := M.copy (| γ0_0 |) in
                                            let b := M.copy (| γ0_1 |) in
                                            M.alloc (|
                                              M.never_to_any (|
                                                M.read (|
                                                  M.return_ (|
                                                    Value.StructTuple
                                                      "core::option::Option::Some"
                                                      [
                                                        Value.Tuple
                                                          [ M.read (| a |); M.read (| b |) ]
                                                      ]
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_struct_tuple (|
                                                γ,
                                                "core::str::pattern::SearchStep::Done"
                                              |) in
                                            M.alloc (|
                                              M.never_to_any (|
                                                M.read (|
                                                  M.return_ (|
                                                    Value.StructTuple
                                                      "core::option::Option::None"
                                                      []
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_struct_tuple (|
                                                γ,
                                                "core::str::pattern::SearchStep::Reject"
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)))
                                |)
                              |)
                            |)
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::str::pattern::StrSearcherImpl::TwoWay",
                              0
                            |) in
                          let searcher := M.alloc (| γ0_0 |) in
                          let~ is_long :=
                            M.alloc (|
                              BinOp.eq (|
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| searcher |),
                                    "core::str::pattern::TwoWaySearcher",
                                    "memory"
                                  |)
                                |),
                                M.read (| M.get_constant (| "core::num::MAX" |) |)
                              |)
                            |) in
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ := M.use is_long in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "core::str::pattern::TwoWaySearcher",
                                        "next_back",
                                        [ Ty.path "core::str::pattern::MatchOnly" ]
                                      |),
                                      [
                                        M.read (| searcher |);
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "str",
                                            "as_bytes",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::StrSearcher",
                                                "haystack"
                                              |)
                                            |)
                                          ]
                                        |);
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "str",
                                            "as_bytes",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::StrSearcher",
                                                "needle"
                                              |)
                                            |)
                                          ]
                                        |);
                                        Value.Bool true
                                      ]
                                    |)
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "core::str::pattern::TwoWaySearcher",
                                        "next_back",
                                        [ Ty.path "core::str::pattern::MatchOnly" ]
                                      |),
                                      [
                                        M.read (| searcher |);
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "str",
                                            "as_bytes",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::StrSearcher",
                                                "haystack"
                                              |)
                                            |)
                                          ]
                                        |);
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "str",
                                            "as_bytes",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::StrSearcher",
                                                "needle"
                                              |)
                                            |)
                                          ]
                                        |);
                                        Value.Bool false
                                      ]
                                    |)
                                  |)))
                            ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::ReverseSearcher"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("next_back", InstanceField.Method next_back);
            ("next_match_back", InstanceField.Method next_match_back)
          ].
    End Impl_core_str_pattern_ReverseSearcher_for_core_str_pattern_StrSearcher.
    
    (* StructRecord
      {
        name := "TwoWaySearcher";
        const_params := [];
        ty_params := [];
        fields :=
          [
            ("crit_pos", Ty.path "usize");
            ("crit_pos_back", Ty.path "usize");
            ("period", Ty.path "usize");
            ("byteset", Ty.path "u64");
            ("position", Ty.path "usize");
            ("end_", Ty.path "usize");
            ("memory", Ty.path "usize");
            ("memory_back", Ty.path "usize")
          ];
      } *)
    
    Module Impl_core_clone_Clone_for_core_str_pattern_TwoWaySearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::TwoWaySearcher".
      
      (* Clone *)
      Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructRecord
              "core::str::pattern::TwoWaySearcher"
              [
                ("crit_pos",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::TwoWaySearcher",
                        "crit_pos"
                      |)
                    ]
                  |));
                ("crit_pos_back",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::TwoWaySearcher",
                        "crit_pos_back"
                      |)
                    ]
                  |));
                ("period",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::TwoWaySearcher",
                        "period"
                      |)
                    ]
                  |));
                ("byteset",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "u64", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::TwoWaySearcher",
                        "byteset"
                      |)
                    ]
                  |));
                ("position",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::TwoWaySearcher",
                        "position"
                      |)
                    ]
                  |));
                ("end_",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::TwoWaySearcher",
                        "end"
                      |)
                    ]
                  |));
                ("memory",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::TwoWaySearcher",
                        "memory"
                      |)
                    ]
                  |));
                ("memory_back",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::TwoWaySearcher",
                        "memory_back"
                      |)
                    ]
                  |))
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::clone::Clone"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method clone) ].
    End Impl_core_clone_Clone_for_core_str_pattern_TwoWaySearcher.
    
    Module Impl_core_fmt_Debug_for_core_str_pattern_TwoWaySearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::TwoWaySearcher".
      
      (* Debug *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.read (|
              let~ names :=
                M.alloc (|
                  M.alloc (|
                    Value.Array
                      [
                        M.read (| Value.String "crit_pos" |);
                        M.read (| Value.String "crit_pos_back" |);
                        M.read (| Value.String "period" |);
                        M.read (| Value.String "byteset" |);
                        M.read (| Value.String "position" |);
                        M.read (| Value.String "end" |);
                        M.read (| Value.String "memory" |);
                        M.read (| Value.String "memory_back" |)
                      ]
                  |)
                |) in
              let~ values :=
                M.alloc (|
                  M.alloc (|
                    Value.Array
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::TwoWaySearcher",
                          "crit_pos"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::TwoWaySearcher",
                          "crit_pos_back"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::TwoWaySearcher",
                          "period"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::TwoWaySearcher",
                          "byteset"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::TwoWaySearcher",
                          "position"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::TwoWaySearcher",
                          "end"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::str::pattern::TwoWaySearcher",
                          "memory"
                        |);
                        M.alloc (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "core::str::pattern::TwoWaySearcher",
                            "memory_back"
                          |)
                        |)
                      ]
                  |)
                |) in
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "core::fmt::Formatter",
                    "debug_struct_fields_finish",
                    []
                  |),
                  [
                    M.read (| f |);
                    M.read (| Value.String "TwoWaySearcher" |);
                    M.read (| names |);
                    M.read (| values |)
                  ]
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Debug"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Debug_for_core_str_pattern_TwoWaySearcher.
    
    Module Impl_core_str_pattern_TwoWaySearcher.
      Definition Self : Ty.t := Ty.path "core::str::pattern::TwoWaySearcher".
      
      (*
          fn new(needle: &[u8], end: usize) -> TwoWaySearcher {
              let (crit_pos_false, period_false) = TwoWaySearcher::maximal_suffix(needle, false);
              let (crit_pos_true, period_true) = TwoWaySearcher::maximal_suffix(needle, true);
      
              let (crit_pos, period) = if crit_pos_false > crit_pos_true {
                  (crit_pos_false, period_false)
              } else {
                  (crit_pos_true, period_true)
              };
      
              // A particularly readable explanation of what's going on here can be found
              // in Crochemore and Rytter's book "Text Algorithms", ch 13. Specifically
              // see the code for "Algorithm CP" on p. 323.
              //
              // What's going on is we have some critical factorization (u, v) of the
              // needle, and we want to determine whether u is a suffix of
              // &v[..period]. If it is, we use "Algorithm CP1". Otherwise we use
              // "Algorithm CP2", which is optimized for when the period of the needle
              // is large.
              if needle[..crit_pos] == needle[period..period + crit_pos] {
                  // short period case -- the period is exact
                  // compute a separate critical factorization for the reversed needle
                  // x = u' v' where |v'| < period(x).
                  //
                  // This is sped up by the period being known already.
                  // Note that a case like x = "acba" may be factored exactly forwards
                  // (crit_pos = 1, period = 3) while being factored with approximate
                  // period in reverse (crit_pos = 2, period = 2). We use the given
                  // reverse factorization but keep the exact period.
                  let crit_pos_back = needle.len()
                      - cmp::max(
                          TwoWaySearcher::reverse_maximal_suffix(needle, period, false),
                          TwoWaySearcher::reverse_maximal_suffix(needle, period, true),
                      );
      
                  TwoWaySearcher {
                      crit_pos,
                      crit_pos_back,
                      period,
                      byteset: Self::byteset_create(&needle[..period]),
      
                      position: 0,
                      end,
                      memory: 0,
                      memory_back: needle.len(),
                  }
              } else {
                  // long period case -- we have an approximation to the actual period,
                  // and don't use memorization.
                  //
                  // Approximate the period by lower bound max(|u|, |v|) + 1.
                  // The critical factorization is efficient to use for both forward and
                  // reverse search.
      
                  TwoWaySearcher {
                      crit_pos,
                      crit_pos_back: crit_pos,
                      period: cmp::max(crit_pos, needle.len() - crit_pos) + 1,
                      byteset: Self::byteset_create(needle),
      
                      position: 0,
                      end,
                      memory: usize::MAX, // Dummy value to signify that the period is long
                      memory_back: usize::MAX,
                  }
              }
          }
      *)
      Definition new (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ needle; end_ ] =>
          ltac:(M.monadic
            (let needle := M.alloc (| needle |) in
            let end_ := M.alloc (| end_ |) in
            M.read (|
              M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "core::str::pattern::TwoWaySearcher",
                      "maximal_suffix",
                      []
                    |),
                    [ M.read (| needle |); Value.Bool false ]
                  |)
                |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                      let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                      let crit_pos_false := M.copy (| γ0_0 |) in
                      let period_false := M.copy (| γ0_1 |) in
                      M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::str::pattern::TwoWaySearcher",
                              "maximal_suffix",
                              []
                            |),
                            [ M.read (| needle |); Value.Bool true ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                              let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                              let crit_pos_true := M.copy (| γ0_0 |) in
                              let period_true := M.copy (| γ0_1 |) in
                              M.match_operator (|
                                M.match_operator (|
                                  M.alloc (| Value.Tuple [] |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ :=
                                          M.use
                                            (M.alloc (|
                                              BinOp.gt (|
                                                M.read (| crit_pos_false |),
                                                M.read (| crit_pos_true |)
                                              |)
                                            |)) in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        M.alloc (|
                                          Value.Tuple
                                            [ M.read (| crit_pos_false |); M.read (| period_false |)
                                            ]
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (M.alloc (|
                                          Value.Tuple
                                            [ M.read (| crit_pos_true |); M.read (| period_true |) ]
                                        |)))
                                  ]
                                |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                      let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                      let crit_pos := M.copy (| γ0_0 |) in
                                      let period := M.copy (| γ0_1 |) in
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    M.call_closure (|
                                                      M.get_trait_method (|
                                                        "core::cmp::PartialEq",
                                                        Ty.apply
                                                          (Ty.path "slice")
                                                          []
                                                          [ Ty.path "u8" ],
                                                        [
                                                          Ty.apply
                                                            (Ty.path "slice")
                                                            []
                                                            [ Ty.path "u8" ]
                                                        ],
                                                        "eq",
                                                        []
                                                      |),
                                                      [
                                                        M.call_closure (|
                                                          M.get_trait_method (|
                                                            "core::ops::index::Index",
                                                            Ty.apply
                                                              (Ty.path "slice")
                                                              []
                                                              [ Ty.path "u8" ],
                                                            [
                                                              Ty.apply
                                                                (Ty.path
                                                                  "core::ops::range::RangeTo")
                                                                []
                                                                [ Ty.path "usize" ]
                                                            ],
                                                            "index",
                                                            []
                                                          |),
                                                          [
                                                            M.read (| needle |);
                                                            Value.StructRecord
                                                              "core::ops::range::RangeTo"
                                                              [ ("end_", M.read (| crit_pos |)) ]
                                                          ]
                                                        |);
                                                        M.call_closure (|
                                                          M.get_trait_method (|
                                                            "core::ops::index::Index",
                                                            Ty.apply
                                                              (Ty.path "slice")
                                                              []
                                                              [ Ty.path "u8" ],
                                                            [
                                                              Ty.apply
                                                                (Ty.path "core::ops::range::Range")
                                                                []
                                                                [ Ty.path "usize" ]
                                                            ],
                                                            "index",
                                                            []
                                                          |),
                                                          [
                                                            M.read (| needle |);
                                                            Value.StructRecord
                                                              "core::ops::range::Range"
                                                              [
                                                                ("start", M.read (| period |));
                                                                ("end_",
                                                                  BinOp.Wrap.add (|
                                                                    M.read (| period |),
                                                                    M.read (| crit_pos |)
                                                                  |))
                                                              ]
                                                          ]
                                                        |)
                                                      ]
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              let~ crit_pos_back :=
                                                M.alloc (|
                                                  BinOp.Wrap.sub (|
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.apply
                                                          (Ty.path "slice")
                                                          []
                                                          [ Ty.path "u8" ],
                                                        "len",
                                                        []
                                                      |),
                                                      [ M.read (| needle |) ]
                                                    |),
                                                    M.call_closure (|
                                                      M.get_function (|
                                                        "core::cmp::max",
                                                        [ Ty.path "usize" ]
                                                      |),
                                                      [
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path
                                                              "core::str::pattern::TwoWaySearcher",
                                                            "reverse_maximal_suffix",
                                                            []
                                                          |),
                                                          [
                                                            M.read (| needle |);
                                                            M.read (| period |);
                                                            Value.Bool false
                                                          ]
                                                        |);
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path
                                                              "core::str::pattern::TwoWaySearcher",
                                                            "reverse_maximal_suffix",
                                                            []
                                                          |),
                                                          [
                                                            M.read (| needle |);
                                                            M.read (| period |);
                                                            Value.Bool true
                                                          ]
                                                        |)
                                                      ]
                                                    |)
                                                  |)
                                                |) in
                                              M.alloc (|
                                                Value.StructRecord
                                                  "core::str::pattern::TwoWaySearcher"
                                                  [
                                                    ("crit_pos", M.read (| crit_pos |));
                                                    ("crit_pos_back", M.read (| crit_pos_back |));
                                                    ("period", M.read (| period |));
                                                    ("byteset",
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.path
                                                            "core::str::pattern::TwoWaySearcher",
                                                          "byteset_create",
                                                          []
                                                        |),
                                                        [
                                                          M.call_closure (|
                                                            M.get_trait_method (|
                                                              "core::ops::index::Index",
                                                              Ty.apply
                                                                (Ty.path "slice")
                                                                []
                                                                [ Ty.path "u8" ],
                                                              [
                                                                Ty.apply
                                                                  (Ty.path
                                                                    "core::ops::range::RangeTo")
                                                                  []
                                                                  [ Ty.path "usize" ]
                                                              ],
                                                              "index",
                                                              []
                                                            |),
                                                            [
                                                              M.read (| needle |);
                                                              Value.StructRecord
                                                                "core::ops::range::RangeTo"
                                                                [ ("end_", M.read (| period |)) ]
                                                            ]
                                                          |)
                                                        ]
                                                      |));
                                                    ("position", Value.Integer IntegerKind.Usize 0);
                                                    ("end_", M.read (| end_ |));
                                                    ("memory", Value.Integer IntegerKind.Usize 0);
                                                    ("memory_back",
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.apply
                                                            (Ty.path "slice")
                                                            []
                                                            [ Ty.path "u8" ],
                                                          "len",
                                                          []
                                                        |),
                                                        [ M.read (| needle |) ]
                                                      |))
                                                  ]
                                              |)));
                                          fun γ =>
                                            ltac:(M.monadic
                                              (M.alloc (|
                                                Value.StructRecord
                                                  "core::str::pattern::TwoWaySearcher"
                                                  [
                                                    ("crit_pos", M.read (| crit_pos |));
                                                    ("crit_pos_back", M.read (| crit_pos |));
                                                    ("period",
                                                      BinOp.Wrap.add (|
                                                        M.call_closure (|
                                                          M.get_function (|
                                                            "core::cmp::max",
                                                            [ Ty.path "usize" ]
                                                          |),
                                                          [
                                                            M.read (| crit_pos |);
                                                            BinOp.Wrap.sub (|
                                                              M.call_closure (|
                                                                M.get_associated_function (|
                                                                  Ty.apply
                                                                    (Ty.path "slice")
                                                                    []
                                                                    [ Ty.path "u8" ],
                                                                  "len",
                                                                  []
                                                                |),
                                                                [ M.read (| needle |) ]
                                                              |),
                                                              M.read (| crit_pos |)
                                                            |)
                                                          ]
                                                        |),
                                                        Value.Integer IntegerKind.Usize 1
                                                      |));
                                                    ("byteset",
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.path
                                                            "core::str::pattern::TwoWaySearcher",
                                                          "byteset_create",
                                                          []
                                                        |),
                                                        [ M.read (| needle |) ]
                                                      |));
                                                    ("position", Value.Integer IntegerKind.Usize 0);
                                                    ("end_", M.read (| end_ |));
                                                    ("memory",
                                                      M.read (|
                                                        M.get_constant (| "core::num::MAX" |)
                                                      |));
                                                    ("memory_back",
                                                      M.read (|
                                                        M.get_constant (| "core::num::MAX" |)
                                                      |))
                                                  ]
                                              |)))
                                        ]
                                      |)))
                                ]
                              |)))
                        ]
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_new : M.IsAssociatedFunction Self "new" new.
      
      (*
          fn byteset_create(bytes: &[u8]) -> u64 {
              bytes.iter().fold(0, |a, &b| (1 << (b & 0x3f)) | a)
          }
      *)
      Definition byteset_create (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ bytes ] =>
          ltac:(M.monadic
            (let bytes := M.alloc (| bytes |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::iter::traits::iterator::Iterator",
                Ty.apply (Ty.path "core::slice::iter::Iter") [] [ Ty.path "u8" ],
                [],
                "fold",
                [
                  Ty.path "u64";
                  Ty.function
                    [ Ty.tuple [ Ty.path "u64"; Ty.apply (Ty.path "&") [] [ Ty.path "u8" ] ] ]
                    (Ty.path "u64")
                ]
              |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                    "iter",
                    []
                  |),
                  [ M.read (| bytes |) ]
                |);
                Value.Integer IntegerKind.U64 0;
                M.closure
                  (fun γ =>
                    ltac:(M.monadic
                      match γ with
                      | [ α0; α1 ] =>
                        ltac:(M.monadic
                          (M.match_operator (|
                            M.alloc (| α0 |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let a := M.copy (| γ |) in
                                  M.match_operator (|
                                    M.alloc (| α1 |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ := M.read (| γ |) in
                                          let b := M.copy (| γ |) in
                                          BinOp.bit_or
                                            (BinOp.Wrap.shl (|
                                              Value.Integer IntegerKind.U64 1,
                                              BinOp.bit_and
                                                (M.read (| b |))
                                                (Value.Integer IntegerKind.U8 63)
                                            |))
                                            (M.read (| a |))))
                                    ]
                                  |)))
                            ]
                          |)))
                      | _ => M.impossible "wrong number of arguments"
                      end))
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_byteset_create :
        M.IsAssociatedFunction Self "byteset_create" byteset_create.
      
      (*
          fn byteset_contains(&self, byte: u8) -> bool {
              (self.byteset >> ((byte & 0x3f) as usize)) & 1 != 0
          }
      *)
      Definition byteset_contains (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; byte ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let byte := M.alloc (| byte |) in
            BinOp.ne (|
              BinOp.bit_and
                (BinOp.Wrap.shr (|
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "core::str::pattern::TwoWaySearcher",
                      "byteset"
                    |)
                  |),
                  M.rust_cast (BinOp.bit_and (M.read (| byte |)) (Value.Integer IntegerKind.U8 63))
                |))
                (Value.Integer IntegerKind.U64 1),
              Value.Integer IntegerKind.U64 0
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_byteset_contains :
        M.IsAssociatedFunction Self "byteset_contains" byteset_contains.
      
      (*
          fn next<S>(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) -> S::Output
          where
              S: TwoWayStrategy,
          {
              // `next()` uses `self.position` as its cursor
              let old_pos = self.position;
              let needle_last = needle.len() - 1;
              'search: loop {
                  // Check that we have room to search in
                  // position + needle_last can not overflow if we assume slices
                  // are bounded by isize's range.
                  let tail_byte = match haystack.get(self.position + needle_last) {
                      Some(&b) => b,
                      None => {
                          self.position = haystack.len();
                          return S::rejecting(old_pos, self.position);
                      }
                  };
      
                  if S::use_early_reject() && old_pos != self.position {
                      return S::rejecting(old_pos, self.position);
                  }
      
                  // Quickly skip by large portions unrelated to our substring
                  if !self.byteset_contains(tail_byte) {
                      self.position += needle.len();
                      if !long_period {
                          self.memory = 0;
                      }
                      continue 'search;
                  }
      
                  // See if the right part of the needle matches
                  let start =
                      if long_period { self.crit_pos } else { cmp::max(self.crit_pos, self.memory) };
                  for i in start..needle.len() {
                      if needle[i] != haystack[self.position + i] {
                          self.position += i - self.crit_pos + 1;
                          if !long_period {
                              self.memory = 0;
                          }
                          continue 'search;
                      }
                  }
      
                  // See if the left part of the needle matches
                  let start = if long_period { 0 } else { self.memory };
                  for i in (start..self.crit_pos).rev() {
                      if needle[i] != haystack[self.position + i] {
                          self.position += self.period;
                          if !long_period {
                              self.memory = needle.len() - self.period;
                          }
                          continue 'search;
                      }
                  }
      
                  // We have found a match!
                  let match_pos = self.position;
      
                  // Note: add self.period instead of needle.len() to have overlapping matches
                  self.position += needle.len();
                  if !long_period {
                      self.memory = 0; // set to needle.len() - self.period for overlapping matches
                  }
      
                  return S::matching(match_pos, match_pos + needle.len());
              }
          }
      *)
      Definition next (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ _ as S ], [ self; haystack; needle; long_period ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            let needle := M.alloc (| needle |) in
            let long_period := M.alloc (| long_period |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ old_pos :=
                    M.copy (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::TwoWaySearcher",
                        "position"
                      |)
                    |) in
                  let~ needle_last :=
                    M.alloc (|
                      BinOp.Wrap.sub (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                            "len",
                            []
                          |),
                          [ M.read (| needle |) ]
                        |),
                        Value.Integer IntegerKind.Usize 1
                      |)
                    |) in
                  M.alloc (|
                    M.never_to_any (|
                      M.read (|
                        M.loop (|
                          ltac:(M.monadic
                            (let~ tail_byte :=
                              M.copy (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                        "get",
                                        [ Ty.path "usize" ]
                                      |),
                                      [
                                        M.read (| haystack |);
                                        BinOp.Wrap.add (|
                                          M.read (|
                                            M.SubPointer.get_struct_record_field (|
                                              M.read (| self |),
                                              "core::str::pattern::TwoWaySearcher",
                                              "position"
                                            |)
                                          |),
                                          M.read (| needle_last |)
                                        |)
                                      ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let γ0_0 := M.read (| γ0_0 |) in
                                        let b := M.copy (| γ0_0 |) in
                                        b));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              let~ _ :=
                                                M.write (|
                                                  M.SubPointer.get_struct_record_field (|
                                                    M.read (| self |),
                                                    "core::str::pattern::TwoWaySearcher",
                                                    "position"
                                                  |),
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "slice")
                                                        []
                                                        [ Ty.path "u8" ],
                                                      "len",
                                                      []
                                                    |),
                                                    [ M.read (| haystack |) ]
                                                  |)
                                                |) in
                                              M.return_ (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::str::pattern::TwoWayStrategy",
                                                    S,
                                                    [],
                                                    "rejecting",
                                                    []
                                                  |),
                                                  [
                                                    M.read (| old_pos |);
                                                    M.read (|
                                                      M.SubPointer.get_struct_record_field (|
                                                        M.read (| self |),
                                                        "core::str::pattern::TwoWaySearcher",
                                                        "position"
                                                      |)
                                                    |)
                                                  ]
                                                |)
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            LogicalOp.and (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::str::pattern::TwoWayStrategy",
                                                  S,
                                                  [],
                                                  "use_early_reject",
                                                  []
                                                |),
                                                []
                                              |),
                                              ltac:(M.monadic
                                                (BinOp.ne (|
                                                  M.read (| old_pos |),
                                                  M.read (|
                                                    M.SubPointer.get_struct_record_field (|
                                                      M.read (| self |),
                                                      "core::str::pattern::TwoWaySearcher",
                                                      "position"
                                                    |)
                                                  |)
                                                |)))
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::str::pattern::TwoWayStrategy",
                                                  S,
                                                  [],
                                                  "rejecting",
                                                  []
                                                |),
                                                [
                                                  M.read (| old_pos |);
                                                  M.read (|
                                                    M.SubPointer.get_struct_record_field (|
                                                      M.read (| self |),
                                                      "core::str::pattern::TwoWaySearcher",
                                                      "position"
                                                    |)
                                                  |)
                                                ]
                                              |)
                                            |)
                                          |)
                                        |)
                                      |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            UnOp.not (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "core::str::pattern::TwoWaySearcher",
                                                  "byteset_contains",
                                                  []
                                                |),
                                                [ M.read (| self |); M.read (| tail_byte |) ]
                                              |)
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            let~ _ :=
                                              let β :=
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::TwoWaySearcher",
                                                  "position"
                                                |) in
                                              M.write (|
                                                β,
                                                BinOp.Wrap.add (|
                                                  M.read (| β |),
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "slice")
                                                        []
                                                        [ Ty.path "u8" ],
                                                      "len",
                                                      []
                                                    |),
                                                    [ M.read (| needle |) ]
                                                  |)
                                                |)
                                              |) in
                                            let~ _ :=
                                              M.match_operator (|
                                                M.alloc (| Value.Tuple [] |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ :=
                                                        M.use
                                                          (M.alloc (|
                                                            UnOp.not (| M.read (| long_period |) |)
                                                          |)) in
                                                      let _ :=
                                                        M.is_constant_or_break_match (|
                                                          M.read (| γ |),
                                                          Value.Bool true
                                                        |) in
                                                      let~ _ :=
                                                        M.write (|
                                                          M.SubPointer.get_struct_record_field (|
                                                            M.read (| self |),
                                                            "core::str::pattern::TwoWaySearcher",
                                                            "memory"
                                                          |),
                                                          Value.Integer IntegerKind.Usize 0
                                                        |) in
                                                      M.alloc (| Value.Tuple [] |)));
                                                  fun γ =>
                                                    ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                                ]
                                              |) in
                                            M.continue (||)
                                          |)
                                        |)
                                      |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ start :=
                              M.copy (|
                                M.match_operator (|
                                  M.alloc (| Value.Tuple [] |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ := M.use long_period in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::TwoWaySearcher",
                                          "crit_pos"
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (M.alloc (|
                                          M.call_closure (|
                                            M.get_function (|
                                              "core::cmp::max",
                                              [ Ty.path "usize" ]
                                            |),
                                            [
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::TwoWaySearcher",
                                                  "crit_pos"
                                                |)
                                              |);
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::TwoWaySearcher",
                                                  "memory"
                                                |)
                                              |)
                                            ]
                                          |)
                                        |)))
                                  ]
                                |)
                              |) in
                            let~ _ :=
                              M.use
                                (M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::collect::IntoIterator",
                                        Ty.apply
                                          (Ty.path "core::ops::range::Range")
                                          []
                                          [ Ty.path "usize" ],
                                        [],
                                        "into_iter",
                                        []
                                      |),
                                      [
                                        Value.StructRecord
                                          "core::ops::range::Range"
                                          [
                                            ("start", M.read (| start |));
                                            ("end_",
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                                  "len",
                                                  []
                                                |),
                                                [ M.read (| needle |) ]
                                              |))
                                          ]
                                      ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let iter := M.copy (| γ |) in
                                        M.loop (|
                                          ltac:(M.monadic
                                            (let~ _ :=
                                              M.match_operator (|
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_trait_method (|
                                                      "core::iter::traits::iterator::Iterator",
                                                      Ty.apply
                                                        (Ty.path "core::ops::range::Range")
                                                        []
                                                        [ Ty.path "usize" ],
                                                      [],
                                                      "next",
                                                      []
                                                    |),
                                                    [ iter ]
                                                  |)
                                                |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let _ :=
                                                        M.is_struct_tuple (|
                                                          γ,
                                                          "core::option::Option::None"
                                                        |) in
                                                      M.alloc (|
                                                        M.never_to_any (|
                                                          M.read (| M.break (||) |)
                                                        |)
                                                      |)));
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ0_0 :=
                                                        M.SubPointer.get_struct_tuple_field (|
                                                          γ,
                                                          "core::option::Option::Some",
                                                          0
                                                        |) in
                                                      let i := M.copy (| γ0_0 |) in
                                                      M.match_operator (|
                                                        M.alloc (| Value.Tuple [] |),
                                                        [
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (let γ :=
                                                                M.use
                                                                  (M.alloc (|
                                                                    BinOp.ne (|
                                                                      M.read (|
                                                                        M.SubPointer.get_array_field (|
                                                                          M.read (| needle |),
                                                                          i
                                                                        |)
                                                                      |),
                                                                      M.read (|
                                                                        M.SubPointer.get_array_field (|
                                                                          M.read (| haystack |),
                                                                          M.alloc (|
                                                                            BinOp.Wrap.add (|
                                                                              M.read (|
                                                                                M.SubPointer.get_struct_record_field (|
                                                                                  M.read (| self |),
                                                                                  "core::str::pattern::TwoWaySearcher",
                                                                                  "position"
                                                                                |)
                                                                              |),
                                                                              M.read (| i |)
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)
                                                                  |)) in
                                                              let _ :=
                                                                M.is_constant_or_break_match (|
                                                                  M.read (| γ |),
                                                                  Value.Bool true
                                                                |) in
                                                              M.alloc (|
                                                                M.never_to_any (|
                                                                  M.read (|
                                                                    let~ _ :=
                                                                      let β :=
                                                                        M.SubPointer.get_struct_record_field (|
                                                                          M.read (| self |),
                                                                          "core::str::pattern::TwoWaySearcher",
                                                                          "position"
                                                                        |) in
                                                                      M.write (|
                                                                        β,
                                                                        BinOp.Wrap.add (|
                                                                          M.read (| β |),
                                                                          BinOp.Wrap.add (|
                                                                            BinOp.Wrap.sub (|
                                                                              M.read (| i |),
                                                                              M.read (|
                                                                                M.SubPointer.get_struct_record_field (|
                                                                                  M.read (| self |),
                                                                                  "core::str::pattern::TwoWaySearcher",
                                                                                  "crit_pos"
                                                                                |)
                                                                              |)
                                                                            |),
                                                                            Value.Integer
                                                                              IntegerKind.Usize
                                                                              1
                                                                          |)
                                                                        |)
                                                                      |) in
                                                                    let~ _ :=
                                                                      M.match_operator (|
                                                                        M.alloc (|
                                                                          Value.Tuple []
                                                                        |),
                                                                        [
                                                                          fun γ =>
                                                                            ltac:(M.monadic
                                                                              (let γ :=
                                                                                M.use
                                                                                  (M.alloc (|
                                                                                    UnOp.not (|
                                                                                      M.read (|
                                                                                        long_period
                                                                                      |)
                                                                                    |)
                                                                                  |)) in
                                                                              let _ :=
                                                                                M.is_constant_or_break_match (|
                                                                                  M.read (| γ |),
                                                                                  Value.Bool true
                                                                                |) in
                                                                              let~ _ :=
                                                                                M.write (|
                                                                                  M.SubPointer.get_struct_record_field (|
                                                                                    M.read (|
                                                                                      self
                                                                                    |),
                                                                                    "core::str::pattern::TwoWaySearcher",
                                                                                    "memory"
                                                                                  |),
                                                                                  Value.Integer
                                                                                    IntegerKind.Usize
                                                                                    0
                                                                                |) in
                                                                              M.alloc (|
                                                                                Value.Tuple []
                                                                              |)));
                                                                          fun γ =>
                                                                            ltac:(M.monadic
                                                                              (M.alloc (|
                                                                                Value.Tuple []
                                                                              |)))
                                                                        ]
                                                                      |) in
                                                                    M.continue (||)
                                                                  |)
                                                                |)
                                                              |)));
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (M.alloc (| Value.Tuple [] |)))
                                                        ]
                                                      |)))
                                                ]
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                        |)))
                                  ]
                                |)) in
                            let~ start :=
                              M.copy (|
                                M.match_operator (|
                                  M.alloc (| Value.Tuple [] |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ := M.use long_period in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        M.alloc (| Value.Integer IntegerKind.Usize 0 |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::TwoWaySearcher",
                                          "memory"
                                        |)))
                                  ]
                                |)
                              |) in
                            let~ _ :=
                              M.use
                                (M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::collect::IntoIterator",
                                        Ty.apply
                                          (Ty.path "core::iter::adapters::rev::Rev")
                                          []
                                          [
                                            Ty.apply
                                              (Ty.path "core::ops::range::Range")
                                              []
                                              [ Ty.path "usize" ]
                                          ],
                                        [],
                                        "into_iter",
                                        []
                                      |),
                                      [
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "core::ops::range::Range")
                                              []
                                              [ Ty.path "usize" ],
                                            [],
                                            "rev",
                                            []
                                          |),
                                          [
                                            Value.StructRecord
                                              "core::ops::range::Range"
                                              [
                                                ("start", M.read (| start |));
                                                ("end_",
                                                  M.read (|
                                                    M.SubPointer.get_struct_record_field (|
                                                      M.read (| self |),
                                                      "core::str::pattern::TwoWaySearcher",
                                                      "crit_pos"
                                                    |)
                                                  |))
                                              ]
                                          ]
                                        |)
                                      ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let iter := M.copy (| γ |) in
                                        M.loop (|
                                          ltac:(M.monadic
                                            (let~ _ :=
                                              M.match_operator (|
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_trait_method (|
                                                      "core::iter::traits::iterator::Iterator",
                                                      Ty.apply
                                                        (Ty.path "core::iter::adapters::rev::Rev")
                                                        []
                                                        [
                                                          Ty.apply
                                                            (Ty.path "core::ops::range::Range")
                                                            []
                                                            [ Ty.path "usize" ]
                                                        ],
                                                      [],
                                                      "next",
                                                      []
                                                    |),
                                                    [ iter ]
                                                  |)
                                                |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let _ :=
                                                        M.is_struct_tuple (|
                                                          γ,
                                                          "core::option::Option::None"
                                                        |) in
                                                      M.alloc (|
                                                        M.never_to_any (|
                                                          M.read (| M.break (||) |)
                                                        |)
                                                      |)));
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ0_0 :=
                                                        M.SubPointer.get_struct_tuple_field (|
                                                          γ,
                                                          "core::option::Option::Some",
                                                          0
                                                        |) in
                                                      let i := M.copy (| γ0_0 |) in
                                                      M.match_operator (|
                                                        M.alloc (| Value.Tuple [] |),
                                                        [
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (let γ :=
                                                                M.use
                                                                  (M.alloc (|
                                                                    BinOp.ne (|
                                                                      M.read (|
                                                                        M.SubPointer.get_array_field (|
                                                                          M.read (| needle |),
                                                                          i
                                                                        |)
                                                                      |),
                                                                      M.read (|
                                                                        M.SubPointer.get_array_field (|
                                                                          M.read (| haystack |),
                                                                          M.alloc (|
                                                                            BinOp.Wrap.add (|
                                                                              M.read (|
                                                                                M.SubPointer.get_struct_record_field (|
                                                                                  M.read (| self |),
                                                                                  "core::str::pattern::TwoWaySearcher",
                                                                                  "position"
                                                                                |)
                                                                              |),
                                                                              M.read (| i |)
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)
                                                                  |)) in
                                                              let _ :=
                                                                M.is_constant_or_break_match (|
                                                                  M.read (| γ |),
                                                                  Value.Bool true
                                                                |) in
                                                              M.alloc (|
                                                                M.never_to_any (|
                                                                  M.read (|
                                                                    let~ _ :=
                                                                      let β :=
                                                                        M.SubPointer.get_struct_record_field (|
                                                                          M.read (| self |),
                                                                          "core::str::pattern::TwoWaySearcher",
                                                                          "position"
                                                                        |) in
                                                                      M.write (|
                                                                        β,
                                                                        BinOp.Wrap.add (|
                                                                          M.read (| β |),
                                                                          M.read (|
                                                                            M.SubPointer.get_struct_record_field (|
                                                                              M.read (| self |),
                                                                              "core::str::pattern::TwoWaySearcher",
                                                                              "period"
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |) in
                                                                    let~ _ :=
                                                                      M.match_operator (|
                                                                        M.alloc (|
                                                                          Value.Tuple []
                                                                        |),
                                                                        [
                                                                          fun γ =>
                                                                            ltac:(M.monadic
                                                                              (let γ :=
                                                                                M.use
                                                                                  (M.alloc (|
                                                                                    UnOp.not (|
                                                                                      M.read (|
                                                                                        long_period
                                                                                      |)
                                                                                    |)
                                                                                  |)) in
                                                                              let _ :=
                                                                                M.is_constant_or_break_match (|
                                                                                  M.read (| γ |),
                                                                                  Value.Bool true
                                                                                |) in
                                                                              let~ _ :=
                                                                                M.write (|
                                                                                  M.SubPointer.get_struct_record_field (|
                                                                                    M.read (|
                                                                                      self
                                                                                    |),
                                                                                    "core::str::pattern::TwoWaySearcher",
                                                                                    "memory"
                                                                                  |),
                                                                                  BinOp.Wrap.sub (|
                                                                                    M.call_closure (|
                                                                                      M.get_associated_function (|
                                                                                        Ty.apply
                                                                                          (Ty.path
                                                                                            "slice")
                                                                                          []
                                                                                          [
                                                                                            Ty.path
                                                                                              "u8"
                                                                                          ],
                                                                                        "len",
                                                                                        []
                                                                                      |),
                                                                                      [
                                                                                        M.read (|
                                                                                          needle
                                                                                        |)
                                                                                      ]
                                                                                    |),
                                                                                    M.read (|
                                                                                      M.SubPointer.get_struct_record_field (|
                                                                                        M.read (|
                                                                                          self
                                                                                        |),
                                                                                        "core::str::pattern::TwoWaySearcher",
                                                                                        "period"
                                                                                      |)
                                                                                    |)
                                                                                  |)
                                                                                |) in
                                                                              M.alloc (|
                                                                                Value.Tuple []
                                                                              |)));
                                                                          fun γ =>
                                                                            ltac:(M.monadic
                                                                              (M.alloc (|
                                                                                Value.Tuple []
                                                                              |)))
                                                                        ]
                                                                      |) in
                                                                    M.continue (||)
                                                                  |)
                                                                |)
                                                              |)));
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (M.alloc (| Value.Tuple [] |)))
                                                        ]
                                                      |)))
                                                ]
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                        |)))
                                  ]
                                |)) in
                            let~ match_pos :=
                              M.copy (|
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::str::pattern::TwoWaySearcher",
                                  "position"
                                |)
                              |) in
                            let~ _ :=
                              let β :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::str::pattern::TwoWaySearcher",
                                  "position"
                                |) in
                              M.write (|
                                β,
                                BinOp.Wrap.add (|
                                  M.read (| β |),
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| needle |) ]
                                  |)
                                |)
                              |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (| UnOp.not (| M.read (| long_period |) |) |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "core::str::pattern::TwoWaySearcher",
                                            "memory"
                                          |),
                                          Value.Integer IntegerKind.Usize 0
                                        |) in
                                      M.alloc (| Value.Tuple [] |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            M.return_ (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::str::pattern::TwoWayStrategy",
                                  S,
                                  [],
                                  "matching",
                                  []
                                |),
                                [
                                  M.read (| match_pos |);
                                  BinOp.Wrap.add (|
                                    M.read (| match_pos |),
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                        "len",
                                        []
                                      |),
                                      [ M.read (| needle |) ]
                                    |)
                                  |)
                                ]
                              |)
                            |)))
                        |)
                      |)
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_next : M.IsAssociatedFunction Self "next" next.
      
      (*
          fn next_back<S>(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) -> S::Output
          where
              S: TwoWayStrategy,
          {
              // `next_back()` uses `self.end` as its cursor -- so that `next()` and `next_back()`
              // are independent.
              let old_end = self.end;
              'search: loop {
                  // Check that we have room to search in
                  // end - needle.len() will wrap around when there is no more room,
                  // but due to slice length limits it can never wrap all the way back
                  // into the length of haystack.
                  let front_byte = match haystack.get(self.end.wrapping_sub(needle.len())) {
                      Some(&b) => b,
                      None => {
                          self.end = 0;
                          return S::rejecting(0, old_end);
                      }
                  };
      
                  if S::use_early_reject() && old_end != self.end {
                      return S::rejecting(self.end, old_end);
                  }
      
                  // Quickly skip by large portions unrelated to our substring
                  if !self.byteset_contains(front_byte) {
                      self.end -= needle.len();
                      if !long_period {
                          self.memory_back = needle.len();
                      }
                      continue 'search;
                  }
      
                  // See if the left part of the needle matches
                  let crit = if long_period {
                      self.crit_pos_back
                  } else {
                      cmp::min(self.crit_pos_back, self.memory_back)
                  };
                  for i in (0..crit).rev() {
                      if needle[i] != haystack[self.end - needle.len() + i] {
                          self.end -= self.crit_pos_back - i;
                          if !long_period {
                              self.memory_back = needle.len();
                          }
                          continue 'search;
                      }
                  }
      
                  // See if the right part of the needle matches
                  let needle_end = if long_period { needle.len() } else { self.memory_back };
                  for i in self.crit_pos_back..needle_end {
                      if needle[i] != haystack[self.end - needle.len() + i] {
                          self.end -= self.period;
                          if !long_period {
                              self.memory_back = self.period;
                          }
                          continue 'search;
                      }
                  }
      
                  // We have found a match!
                  let match_pos = self.end - needle.len();
                  // Note: sub self.period instead of needle.len() to have overlapping matches
                  self.end -= needle.len();
                  if !long_period {
                      self.memory_back = needle.len();
                  }
      
                  return S::matching(match_pos, match_pos + needle.len());
              }
          }
      *)
      Definition next_back (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ _ as S ], [ self; haystack; needle; long_period ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let haystack := M.alloc (| haystack |) in
            let needle := M.alloc (| needle |) in
            let long_period := M.alloc (| long_period |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ old_end :=
                    M.copy (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::str::pattern::TwoWaySearcher",
                        "end"
                      |)
                    |) in
                  M.alloc (|
                    M.never_to_any (|
                      M.read (|
                        M.loop (|
                          ltac:(M.monadic
                            (let~ front_byte :=
                              M.copy (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                        "get",
                                        [ Ty.path "usize" ]
                                      |),
                                      [
                                        M.read (| haystack |);
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "usize",
                                            "wrapping_sub",
                                            []
                                          |),
                                          [
                                            M.read (|
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "core::str::pattern::TwoWaySearcher",
                                                "end"
                                              |)
                                            |);
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                                "len",
                                                []
                                              |),
                                              [ M.read (| needle |) ]
                                            |)
                                          ]
                                        |)
                                      ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let γ0_0 := M.read (| γ0_0 |) in
                                        let b := M.copy (| γ0_0 |) in
                                        b));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              let~ _ :=
                                                M.write (|
                                                  M.SubPointer.get_struct_record_field (|
                                                    M.read (| self |),
                                                    "core::str::pattern::TwoWaySearcher",
                                                    "end"
                                                  |),
                                                  Value.Integer IntegerKind.Usize 0
                                                |) in
                                              M.return_ (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::str::pattern::TwoWayStrategy",
                                                    S,
                                                    [],
                                                    "rejecting",
                                                    []
                                                  |),
                                                  [
                                                    Value.Integer IntegerKind.Usize 0;
                                                    M.read (| old_end |)
                                                  ]
                                                |)
                                              |)
                                            |)
                                          |)
                                        |)))
                                  ]
                                |)
                              |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            LogicalOp.and (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::str::pattern::TwoWayStrategy",
                                                  S,
                                                  [],
                                                  "use_early_reject",
                                                  []
                                                |),
                                                []
                                              |),
                                              ltac:(M.monadic
                                                (BinOp.ne (|
                                                  M.read (| old_end |),
                                                  M.read (|
                                                    M.SubPointer.get_struct_record_field (|
                                                      M.read (| self |),
                                                      "core::str::pattern::TwoWaySearcher",
                                                      "end"
                                                    |)
                                                  |)
                                                |)))
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::str::pattern::TwoWayStrategy",
                                                  S,
                                                  [],
                                                  "rejecting",
                                                  []
                                                |),
                                                [
                                                  M.read (|
                                                    M.SubPointer.get_struct_record_field (|
                                                      M.read (| self |),
                                                      "core::str::pattern::TwoWaySearcher",
                                                      "end"
                                                    |)
                                                  |);
                                                  M.read (| old_end |)
                                                ]
                                              |)
                                            |)
                                          |)
                                        |)
                                      |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            UnOp.not (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "core::str::pattern::TwoWaySearcher",
                                                  "byteset_contains",
                                                  []
                                                |),
                                                [ M.read (| self |); M.read (| front_byte |) ]
                                              |)
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            let~ _ :=
                                              let β :=
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::TwoWaySearcher",
                                                  "end"
                                                |) in
                                              M.write (|
                                                β,
                                                BinOp.Wrap.sub (|
                                                  M.read (| β |),
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "slice")
                                                        []
                                                        [ Ty.path "u8" ],
                                                      "len",
                                                      []
                                                    |),
                                                    [ M.read (| needle |) ]
                                                  |)
                                                |)
                                              |) in
                                            let~ _ :=
                                              M.match_operator (|
                                                M.alloc (| Value.Tuple [] |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ :=
                                                        M.use
                                                          (M.alloc (|
                                                            UnOp.not (| M.read (| long_period |) |)
                                                          |)) in
                                                      let _ :=
                                                        M.is_constant_or_break_match (|
                                                          M.read (| γ |),
                                                          Value.Bool true
                                                        |) in
                                                      let~ _ :=
                                                        M.write (|
                                                          M.SubPointer.get_struct_record_field (|
                                                            M.read (| self |),
                                                            "core::str::pattern::TwoWaySearcher",
                                                            "memory_back"
                                                          |),
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path "slice")
                                                                []
                                                                [ Ty.path "u8" ],
                                                              "len",
                                                              []
                                                            |),
                                                            [ M.read (| needle |) ]
                                                          |)
                                                        |) in
                                                      M.alloc (| Value.Tuple [] |)));
                                                  fun γ =>
                                                    ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                                ]
                                              |) in
                                            M.continue (||)
                                          |)
                                        |)
                                      |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ crit :=
                              M.copy (|
                                M.match_operator (|
                                  M.alloc (| Value.Tuple [] |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ := M.use long_period in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::TwoWaySearcher",
                                          "crit_pos_back"
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (M.alloc (|
                                          M.call_closure (|
                                            M.get_function (|
                                              "core::cmp::min",
                                              [ Ty.path "usize" ]
                                            |),
                                            [
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::TwoWaySearcher",
                                                  "crit_pos_back"
                                                |)
                                              |);
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::TwoWaySearcher",
                                                  "memory_back"
                                                |)
                                              |)
                                            ]
                                          |)
                                        |)))
                                  ]
                                |)
                              |) in
                            let~ _ :=
                              M.use
                                (M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::collect::IntoIterator",
                                        Ty.apply
                                          (Ty.path "core::iter::adapters::rev::Rev")
                                          []
                                          [
                                            Ty.apply
                                              (Ty.path "core::ops::range::Range")
                                              []
                                              [ Ty.path "usize" ]
                                          ],
                                        [],
                                        "into_iter",
                                        []
                                      |),
                                      [
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "core::ops::range::Range")
                                              []
                                              [ Ty.path "usize" ],
                                            [],
                                            "rev",
                                            []
                                          |),
                                          [
                                            Value.StructRecord
                                              "core::ops::range::Range"
                                              [
                                                ("start", Value.Integer IntegerKind.Usize 0);
                                                ("end_", M.read (| crit |))
                                              ]
                                          ]
                                        |)
                                      ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let iter := M.copy (| γ |) in
                                        M.loop (|
                                          ltac:(M.monadic
                                            (let~ _ :=
                                              M.match_operator (|
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_trait_method (|
                                                      "core::iter::traits::iterator::Iterator",
                                                      Ty.apply
                                                        (Ty.path "core::iter::adapters::rev::Rev")
                                                        []
                                                        [
                                                          Ty.apply
                                                            (Ty.path "core::ops::range::Range")
                                                            []
                                                            [ Ty.path "usize" ]
                                                        ],
                                                      [],
                                                      "next",
                                                      []
                                                    |),
                                                    [ iter ]
                                                  |)
                                                |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let _ :=
                                                        M.is_struct_tuple (|
                                                          γ,
                                                          "core::option::Option::None"
                                                        |) in
                                                      M.alloc (|
                                                        M.never_to_any (|
                                                          M.read (| M.break (||) |)
                                                        |)
                                                      |)));
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ0_0 :=
                                                        M.SubPointer.get_struct_tuple_field (|
                                                          γ,
                                                          "core::option::Option::Some",
                                                          0
                                                        |) in
                                                      let i := M.copy (| γ0_0 |) in
                                                      M.match_operator (|
                                                        M.alloc (| Value.Tuple [] |),
                                                        [
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (let γ :=
                                                                M.use
                                                                  (M.alloc (|
                                                                    BinOp.ne (|
                                                                      M.read (|
                                                                        M.SubPointer.get_array_field (|
                                                                          M.read (| needle |),
                                                                          i
                                                                        |)
                                                                      |),
                                                                      M.read (|
                                                                        M.SubPointer.get_array_field (|
                                                                          M.read (| haystack |),
                                                                          M.alloc (|
                                                                            BinOp.Wrap.add (|
                                                                              BinOp.Wrap.sub (|
                                                                                M.read (|
                                                                                  M.SubPointer.get_struct_record_field (|
                                                                                    M.read (|
                                                                                      self
                                                                                    |),
                                                                                    "core::str::pattern::TwoWaySearcher",
                                                                                    "end"
                                                                                  |)
                                                                                |),
                                                                                M.call_closure (|
                                                                                  M.get_associated_function (|
                                                                                    Ty.apply
                                                                                      (Ty.path
                                                                                        "slice")
                                                                                      []
                                                                                      [ Ty.path "u8"
                                                                                      ],
                                                                                    "len",
                                                                                    []
                                                                                  |),
                                                                                  [
                                                                                    M.read (|
                                                                                      needle
                                                                                    |)
                                                                                  ]
                                                                                |)
                                                                              |),
                                                                              M.read (| i |)
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)
                                                                  |)) in
                                                              let _ :=
                                                                M.is_constant_or_break_match (|
                                                                  M.read (| γ |),
                                                                  Value.Bool true
                                                                |) in
                                                              M.alloc (|
                                                                M.never_to_any (|
                                                                  M.read (|
                                                                    let~ _ :=
                                                                      let β :=
                                                                        M.SubPointer.get_struct_record_field (|
                                                                          M.read (| self |),
                                                                          "core::str::pattern::TwoWaySearcher",
                                                                          "end"
                                                                        |) in
                                                                      M.write (|
                                                                        β,
                                                                        BinOp.Wrap.sub (|
                                                                          M.read (| β |),
                                                                          BinOp.Wrap.sub (|
                                                                            M.read (|
                                                                              M.SubPointer.get_struct_record_field (|
                                                                                M.read (| self |),
                                                                                "core::str::pattern::TwoWaySearcher",
                                                                                "crit_pos_back"
                                                                              |)
                                                                            |),
                                                                            M.read (| i |)
                                                                          |)
                                                                        |)
                                                                      |) in
                                                                    let~ _ :=
                                                                      M.match_operator (|
                                                                        M.alloc (|
                                                                          Value.Tuple []
                                                                        |),
                                                                        [
                                                                          fun γ =>
                                                                            ltac:(M.monadic
                                                                              (let γ :=
                                                                                M.use
                                                                                  (M.alloc (|
                                                                                    UnOp.not (|
                                                                                      M.read (|
                                                                                        long_period
                                                                                      |)
                                                                                    |)
                                                                                  |)) in
                                                                              let _ :=
                                                                                M.is_constant_or_break_match (|
                                                                                  M.read (| γ |),
                                                                                  Value.Bool true
                                                                                |) in
                                                                              let~ _ :=
                                                                                M.write (|
                                                                                  M.SubPointer.get_struct_record_field (|
                                                                                    M.read (|
                                                                                      self
                                                                                    |),
                                                                                    "core::str::pattern::TwoWaySearcher",
                                                                                    "memory_back"
                                                                                  |),
                                                                                  M.call_closure (|
                                                                                    M.get_associated_function (|
                                                                                      Ty.apply
                                                                                        (Ty.path
                                                                                          "slice")
                                                                                        []
                                                                                        [
                                                                                          Ty.path
                                                                                            "u8"
                                                                                        ],
                                                                                      "len",
                                                                                      []
                                                                                    |),
                                                                                    [
                                                                                      M.read (|
                                                                                        needle
                                                                                      |)
                                                                                    ]
                                                                                  |)
                                                                                |) in
                                                                              M.alloc (|
                                                                                Value.Tuple []
                                                                              |)));
                                                                          fun γ =>
                                                                            ltac:(M.monadic
                                                                              (M.alloc (|
                                                                                Value.Tuple []
                                                                              |)))
                                                                        ]
                                                                      |) in
                                                                    M.continue (||)
                                                                  |)
                                                                |)
                                                              |)));
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (M.alloc (| Value.Tuple [] |)))
                                                        ]
                                                      |)))
                                                ]
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                        |)))
                                  ]
                                |)) in
                            let~ needle_end :=
                              M.copy (|
                                M.match_operator (|
                                  M.alloc (| Value.Tuple [] |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ := M.use long_period in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        M.alloc (|
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                              "len",
                                              []
                                            |),
                                            [ M.read (| needle |) ]
                                          |)
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "core::str::pattern::TwoWaySearcher",
                                          "memory_back"
                                        |)))
                                  ]
                                |)
                              |) in
                            let~ _ :=
                              M.use
                                (M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::collect::IntoIterator",
                                        Ty.apply
                                          (Ty.path "core::ops::range::Range")
                                          []
                                          [ Ty.path "usize" ],
                                        [],
                                        "into_iter",
                                        []
                                      |),
                                      [
                                        Value.StructRecord
                                          "core::ops::range::Range"
                                          [
                                            ("start",
                                              M.read (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "core::str::pattern::TwoWaySearcher",
                                                  "crit_pos_back"
                                                |)
                                              |));
                                            ("end_", M.read (| needle_end |))
                                          ]
                                      ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let iter := M.copy (| γ |) in
                                        M.loop (|
                                          ltac:(M.monadic
                                            (let~ _ :=
                                              M.match_operator (|
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_trait_method (|
                                                      "core::iter::traits::iterator::Iterator",
                                                      Ty.apply
                                                        (Ty.path "core::ops::range::Range")
                                                        []
                                                        [ Ty.path "usize" ],
                                                      [],
                                                      "next",
                                                      []
                                                    |),
                                                    [ iter ]
                                                  |)
                                                |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let _ :=
                                                        M.is_struct_tuple (|
                                                          γ,
                                                          "core::option::Option::None"
                                                        |) in
                                                      M.alloc (|
                                                        M.never_to_any (|
                                                          M.read (| M.break (||) |)
                                                        |)
                                                      |)));
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ0_0 :=
                                                        M.SubPointer.get_struct_tuple_field (|
                                                          γ,
                                                          "core::option::Option::Some",
                                                          0
                                                        |) in
                                                      let i := M.copy (| γ0_0 |) in
                                                      M.match_operator (|
                                                        M.alloc (| Value.Tuple [] |),
                                                        [
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (let γ :=
                                                                M.use
                                                                  (M.alloc (|
                                                                    BinOp.ne (|
                                                                      M.read (|
                                                                        M.SubPointer.get_array_field (|
                                                                          M.read (| needle |),
                                                                          i
                                                                        |)
                                                                      |),
                                                                      M.read (|
                                                                        M.SubPointer.get_array_field (|
                                                                          M.read (| haystack |),
                                                                          M.alloc (|
                                                                            BinOp.Wrap.add (|
                                                                              BinOp.Wrap.sub (|
                                                                                M.read (|
                                                                                  M.SubPointer.get_struct_record_field (|
                                                                                    M.read (|
                                                                                      self
                                                                                    |),
                                                                                    "core::str::pattern::TwoWaySearcher",
                                                                                    "end"
                                                                                  |)
                                                                                |),
                                                                                M.call_closure (|
                                                                                  M.get_associated_function (|
                                                                                    Ty.apply
                                                                                      (Ty.path
                                                                                        "slice")
                                                                                      []
                                                                                      [ Ty.path "u8"
                                                                                      ],
                                                                                    "len",
                                                                                    []
                                                                                  |),
                                                                                  [
                                                                                    M.read (|
                                                                                      needle
                                                                                    |)
                                                                                  ]
                                                                                |)
                                                                              |),
                                                                              M.read (| i |)
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)
                                                                  |)) in
                                                              let _ :=
                                                                M.is_constant_or_break_match (|
                                                                  M.read (| γ |),
                                                                  Value.Bool true
                                                                |) in
                                                              M.alloc (|
                                                                M.never_to_any (|
                                                                  M.read (|
                                                                    let~ _ :=
                                                                      let β :=
                                                                        M.SubPointer.get_struct_record_field (|
                                                                          M.read (| self |),
                                                                          "core::str::pattern::TwoWaySearcher",
                                                                          "end"
                                                                        |) in
                                                                      M.write (|
                                                                        β,
                                                                        BinOp.Wrap.sub (|
                                                                          M.read (| β |),
                                                                          M.read (|
                                                                            M.SubPointer.get_struct_record_field (|
                                                                              M.read (| self |),
                                                                              "core::str::pattern::TwoWaySearcher",
                                                                              "period"
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |) in
                                                                    let~ _ :=
                                                                      M.match_operator (|
                                                                        M.alloc (|
                                                                          Value.Tuple []
                                                                        |),
                                                                        [
                                                                          fun γ =>
                                                                            ltac:(M.monadic
                                                                              (let γ :=
                                                                                M.use
                                                                                  (M.alloc (|
                                                                                    UnOp.not (|
                                                                                      M.read (|
                                                                                        long_period
                                                                                      |)
                                                                                    |)
                                                                                  |)) in
                                                                              let _ :=
                                                                                M.is_constant_or_break_match (|
                                                                                  M.read (| γ |),
                                                                                  Value.Bool true
                                                                                |) in
                                                                              let~ _ :=
                                                                                M.write (|
                                                                                  M.SubPointer.get_struct_record_field (|
                                                                                    M.read (|
                                                                                      self
                                                                                    |),
                                                                                    "core::str::pattern::TwoWaySearcher",
                                                                                    "memory_back"
                                                                                  |),
                                                                                  M.read (|
                                                                                    M.SubPointer.get_struct_record_field (|
                                                                                      M.read (|
                                                                                        self
                                                                                      |),
                                                                                      "core::str::pattern::TwoWaySearcher",
                                                                                      "period"
                                                                                    |)
                                                                                  |)
                                                                                |) in
                                                                              M.alloc (|
                                                                                Value.Tuple []
                                                                              |)));
                                                                          fun γ =>
                                                                            ltac:(M.monadic
                                                                              (M.alloc (|
                                                                                Value.Tuple []
                                                                              |)))
                                                                        ]
                                                                      |) in
                                                                    M.continue (||)
                                                                  |)
                                                                |)
                                                              |)));
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (M.alloc (| Value.Tuple [] |)))
                                                        ]
                                                      |)))
                                                ]
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                        |)))
                                  ]
                                |)) in
                            let~ match_pos :=
                              M.alloc (|
                                BinOp.Wrap.sub (|
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "core::str::pattern::TwoWaySearcher",
                                      "end"
                                    |)
                                  |),
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| needle |) ]
                                  |)
                                |)
                              |) in
                            let~ _ :=
                              let β :=
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "core::str::pattern::TwoWaySearcher",
                                  "end"
                                |) in
                              M.write (|
                                β,
                                BinOp.Wrap.sub (|
                                  M.read (| β |),
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| needle |) ]
                                  |)
                                |)
                              |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (| UnOp.not (| M.read (| long_period |) |) |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      let~ _ :=
                                        M.write (|
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "core::str::pattern::TwoWaySearcher",
                                            "memory_back"
                                          |),
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                              "len",
                                              []
                                            |),
                                            [ M.read (| needle |) ]
                                          |)
                                        |) in
                                      M.alloc (| Value.Tuple [] |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            M.return_ (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::str::pattern::TwoWayStrategy",
                                  S,
                                  [],
                                  "matching",
                                  []
                                |),
                                [
                                  M.read (| match_pos |);
                                  BinOp.Wrap.add (|
                                    M.read (| match_pos |),
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                        "len",
                                        []
                                      |),
                                      [ M.read (| needle |) ]
                                    |)
                                  |)
                                ]
                              |)
                            |)))
                        |)
                      |)
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_next_back : M.IsAssociatedFunction Self "next_back" next_back.
      
      (*
          fn maximal_suffix(arr: &[u8], order_greater: bool) -> (usize, usize) {
              let mut left = 0; // Corresponds to i in the paper
              let mut right = 1; // Corresponds to j in the paper
              let mut offset = 0; // Corresponds to k in the paper, but starting at 0
              // to match 0-based indexing.
              let mut period = 1; // Corresponds to p in the paper
      
              while let Some(&a) = arr.get(right + offset) {
                  // `left` will be inbounds when `right` is.
                  let b = arr[left + offset];
                  if (a < b && !order_greater) || (a > b && order_greater) {
                      // Suffix is smaller, period is entire prefix so far.
                      right += offset + 1;
                      offset = 0;
                      period = right - left;
                  } else if a == b {
                      // Advance through repetition of the current period.
                      if offset + 1 == period {
                          right += offset + 1;
                          offset = 0;
                      } else {
                          offset += 1;
                      }
                  } else {
                      // Suffix is larger, start over from current location.
                      left = right;
                      right += 1;
                      offset = 0;
                      period = 1;
                  }
              }
              (left, period)
          }
      *)
      Definition maximal_suffix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ arr; order_greater ] =>
          ltac:(M.monadic
            (let arr := M.alloc (| arr |) in
            let order_greater := M.alloc (| order_greater |) in
            M.read (|
              let~ left := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
              let~ right := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
              let~ offset := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
              let~ period := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
              let~ _ :=
                M.loop (|
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                    "get",
                                    [ Ty.path "usize" ]
                                  |),
                                  [
                                    M.read (| arr |);
                                    BinOp.Wrap.add (| M.read (| right |), M.read (| offset |) |)
                                  ]
                                |)
                              |) in
                            let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let γ0_0 := M.read (| γ0_0 |) in
                            let a := M.copy (| γ0_0 |) in
                            let~ b :=
                              M.copy (|
                                M.SubPointer.get_array_field (|
                                  M.read (| arr |),
                                  M.alloc (|
                                    BinOp.Wrap.add (| M.read (| left |), M.read (| offset |) |)
                                  |)
                                |)
                              |) in
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          LogicalOp.or (|
                                            LogicalOp.and (|
                                              BinOp.lt (| M.read (| a |), M.read (| b |) |),
                                              ltac:(M.monadic
                                                (UnOp.not (| M.read (| order_greater |) |)))
                                            |),
                                            ltac:(M.monadic
                                              (LogicalOp.and (|
                                                BinOp.gt (| M.read (| a |), M.read (| b |) |),
                                                ltac:(M.monadic (M.read (| order_greater |)))
                                              |)))
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      let β := right in
                                      M.write (|
                                        β,
                                        BinOp.Wrap.add (|
                                          M.read (| β |),
                                          BinOp.Wrap.add (|
                                            M.read (| offset |),
                                            Value.Integer IntegerKind.Usize 1
                                          |)
                                        |)
                                      |) in
                                    let~ _ :=
                                      M.write (| offset, Value.Integer IntegerKind.Usize 0 |) in
                                    let~ _ :=
                                      M.write (|
                                        period,
                                        BinOp.Wrap.sub (| M.read (| right |), M.read (| left |) |)
                                      |) in
                                    M.alloc (| Value.Tuple [] |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.eq (| M.read (| a |), M.read (| b |) |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.eq (|
                                                            BinOp.Wrap.add (|
                                                              M.read (| offset |),
                                                              Value.Integer IntegerKind.Usize 1
                                                            |),
                                                            M.read (| period |)
                                                          |)
                                                        |)) in
                                                    let _ :=
                                                      M.is_constant_or_break_match (|
                                                        M.read (| γ |),
                                                        Value.Bool true
                                                      |) in
                                                    let~ _ :=
                                                      let β := right in
                                                      M.write (|
                                                        β,
                                                        BinOp.Wrap.add (|
                                                          M.read (| β |),
                                                          BinOp.Wrap.add (|
                                                            M.read (| offset |),
                                                            Value.Integer IntegerKind.Usize 1
                                                          |)
                                                        |)
                                                      |) in
                                                    let~ _ :=
                                                      M.write (|
                                                        offset,
                                                        Value.Integer IntegerKind.Usize 0
                                                      |) in
                                                    M.alloc (| Value.Tuple [] |)));
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let~ _ :=
                                                      let β := offset in
                                                      M.write (|
                                                        β,
                                                        BinOp.Wrap.add (|
                                                          M.read (| β |),
                                                          Value.Integer IntegerKind.Usize 1
                                                        |)
                                                      |) in
                                                    M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let~ _ := M.write (| left, M.read (| right |) |) in
                                            let~ _ :=
                                              let β := right in
                                              M.write (|
                                                β,
                                                BinOp.Wrap.add (|
                                                  M.read (| β |),
                                                  Value.Integer IntegerKind.Usize 1
                                                |)
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                offset,
                                                Value.Integer IntegerKind.Usize 0
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                period,
                                                Value.Integer IntegerKind.Usize 1
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)))
                              ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  let~ _ :=
                                    M.alloc (| M.never_to_any (| M.read (| M.break (||) |) |) |) in
                                  M.alloc (| Value.Tuple [] |)
                                |)
                              |)
                            |)))
                      ]
                    |)))
                |) in
              M.alloc (| Value.Tuple [ M.read (| left |); M.read (| period |) ] |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_maximal_suffix :
        M.IsAssociatedFunction Self "maximal_suffix" maximal_suffix.
      
      (*
          fn reverse_maximal_suffix(arr: &[u8], known_period: usize, order_greater: bool) -> usize {
              let mut left = 0; // Corresponds to i in the paper
              let mut right = 1; // Corresponds to j in the paper
              let mut offset = 0; // Corresponds to k in the paper, but starting at 0
              // to match 0-based indexing.
              let mut period = 1; // Corresponds to p in the paper
              let n = arr.len();
      
              while right + offset < n {
                  let a = arr[n - (1 + right + offset)];
                  let b = arr[n - (1 + left + offset)];
                  if (a < b && !order_greater) || (a > b && order_greater) {
                      // Suffix is smaller, period is entire prefix so far.
                      right += offset + 1;
                      offset = 0;
                      period = right - left;
                  } else if a == b {
                      // Advance through repetition of the current period.
                      if offset + 1 == period {
                          right += offset + 1;
                          offset = 0;
                      } else {
                          offset += 1;
                      }
                  } else {
                      // Suffix is larger, start over from current location.
                      left = right;
                      right += 1;
                      offset = 0;
                      period = 1;
                  }
                  if period == known_period {
                      break;
                  }
              }
              debug_assert!(period <= known_period);
              left
          }
      *)
      Definition reverse_maximal_suffix (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ arr; known_period; order_greater ] =>
          ltac:(M.monadic
            (let arr := M.alloc (| arr |) in
            let known_period := M.alloc (| known_period |) in
            let order_greater := M.alloc (| order_greater |) in
            M.read (|
              let~ left := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
              let~ right := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
              let~ offset := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
              let~ period := M.alloc (| Value.Integer IntegerKind.Usize 1 |) in
              let~ n :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                      "len",
                      []
                    |),
                    [ M.read (| arr |) ]
                  |)
                |) in
              let~ _ :=
                M.loop (|
                  ltac:(M.monadic
                    (M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.lt (|
                                    BinOp.Wrap.add (| M.read (| right |), M.read (| offset |) |),
                                    M.read (| n |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            let~ a :=
                              M.copy (|
                                M.SubPointer.get_array_field (|
                                  M.read (| arr |),
                                  M.alloc (|
                                    BinOp.Wrap.sub (|
                                      M.read (| n |),
                                      BinOp.Wrap.add (|
                                        BinOp.Wrap.add (|
                                          Value.Integer IntegerKind.Usize 1,
                                          M.read (| right |)
                                        |),
                                        M.read (| offset |)
                                      |)
                                    |)
                                  |)
                                |)
                              |) in
                            let~ b :=
                              M.copy (|
                                M.SubPointer.get_array_field (|
                                  M.read (| arr |),
                                  M.alloc (|
                                    BinOp.Wrap.sub (|
                                      M.read (| n |),
                                      BinOp.Wrap.add (|
                                        BinOp.Wrap.add (|
                                          Value.Integer IntegerKind.Usize 1,
                                          M.read (| left |)
                                        |),
                                        M.read (| offset |)
                                      |)
                                    |)
                                  |)
                                |)
                              |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            LogicalOp.or (|
                                              LogicalOp.and (|
                                                BinOp.lt (| M.read (| a |), M.read (| b |) |),
                                                ltac:(M.monadic
                                                  (UnOp.not (| M.read (| order_greater |) |)))
                                              |),
                                              ltac:(M.monadic
                                                (LogicalOp.and (|
                                                  BinOp.gt (| M.read (| a |), M.read (| b |) |),
                                                  ltac:(M.monadic (M.read (| order_greater |)))
                                                |)))
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      let~ _ :=
                                        let β := right in
                                        M.write (|
                                          β,
                                          BinOp.Wrap.add (|
                                            M.read (| β |),
                                            BinOp.Wrap.add (|
                                              M.read (| offset |),
                                              Value.Integer IntegerKind.Usize 1
                                            |)
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.write (| offset, Value.Integer IntegerKind.Usize 0 |) in
                                      let~ _ :=
                                        M.write (|
                                          period,
                                          BinOp.Wrap.sub (| M.read (| right |), M.read (| left |) |)
                                        |) in
                                      M.alloc (| Value.Tuple [] |)));
                                  fun γ =>
                                    ltac:(M.monadic
                                      (M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.eq (| M.read (| a |), M.read (| b |) |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              M.match_operator (|
                                                M.alloc (| Value.Tuple [] |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ :=
                                                        M.use
                                                          (M.alloc (|
                                                            BinOp.eq (|
                                                              BinOp.Wrap.add (|
                                                                M.read (| offset |),
                                                                Value.Integer IntegerKind.Usize 1
                                                              |),
                                                              M.read (| period |)
                                                            |)
                                                          |)) in
                                                      let _ :=
                                                        M.is_constant_or_break_match (|
                                                          M.read (| γ |),
                                                          Value.Bool true
                                                        |) in
                                                      let~ _ :=
                                                        let β := right in
                                                        M.write (|
                                                          β,
                                                          BinOp.Wrap.add (|
                                                            M.read (| β |),
                                                            BinOp.Wrap.add (|
                                                              M.read (| offset |),
                                                              Value.Integer IntegerKind.Usize 1
                                                            |)
                                                          |)
                                                        |) in
                                                      let~ _ :=
                                                        M.write (|
                                                          offset,
                                                          Value.Integer IntegerKind.Usize 0
                                                        |) in
                                                      M.alloc (| Value.Tuple [] |)));
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let~ _ :=
                                                        let β := offset in
                                                        M.write (|
                                                          β,
                                                          BinOp.Wrap.add (|
                                                            M.read (| β |),
                                                            Value.Integer IntegerKind.Usize 1
                                                          |)
                                                        |) in
                                                      M.alloc (| Value.Tuple [] |)))
                                                ]
                                              |)));
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let~ _ := M.write (| left, M.read (| right |) |) in
                                              let~ _ :=
                                                let β := right in
                                                M.write (|
                                                  β,
                                                  BinOp.Wrap.add (|
                                                    M.read (| β |),
                                                    Value.Integer IntegerKind.Usize 1
                                                  |)
                                                |) in
                                              let~ _ :=
                                                M.write (|
                                                  offset,
                                                  Value.Integer IntegerKind.Usize 0
                                                |) in
                                              let~ _ :=
                                                M.write (|
                                                  period,
                                                  Value.Integer IntegerKind.Usize 1
                                                |) in
                                              M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |)))
                                ]
                              |) in
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.eq (|
                                            M.read (| period |),
                                            M.read (| known_period |)
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.alloc (| M.never_to_any (| M.read (| M.break (||) |) |) |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  let~ _ :=
                                    M.alloc (| M.never_to_any (| M.read (| M.break (||) |) |) |) in
                                  M.alloc (| Value.Tuple [] |)
                                |)
                              |)
                            |)))
                      ]
                    |)))
                |) in
              let~ _ :=
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.use (M.alloc (| Value.Bool true |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        let~ _ :=
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ :=
                                    M.use
                                      (M.alloc (|
                                        UnOp.not (|
                                          BinOp.le (|
                                            M.read (| period |),
                                            M.read (| known_period |)
                                          |)
                                        |)
                                      |)) in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  M.alloc (|
                                    M.never_to_any (|
                                      M.call_closure (|
                                        M.get_function (| "core::panicking::panic", [] |),
                                        [
                                          M.read (|
                                            Value.String "assertion failed: period <= known_period"
                                          |)
                                        ]
                                      |)
                                    |)
                                  |)));
                              fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                            ]
                          |) in
                        M.alloc (| Value.Tuple [] |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                  ]
                |) in
              left
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_reverse_maximal_suffix :
        M.IsAssociatedFunction Self "reverse_maximal_suffix" reverse_maximal_suffix.
    End Impl_core_str_pattern_TwoWaySearcher.
    
    (* Trait *)
    (* Empty module 'TwoWayStrategy' *)
    
    (*
    Enum MatchOnly
    {
      const_params := [];
      ty_params := [];
      variants := [];
    }
    *)
    
    Module Impl_core_str_pattern_TwoWayStrategy_for_core_str_pattern_MatchOnly.
      Definition Self : Ty.t := Ty.path "core::str::pattern::MatchOnly".
      
      (*     type Output = Option<(usize, usize)>; *)
      Definition _Output : Ty.t :=
        Ty.apply
          (Ty.path "core::option::Option")
          []
          [ Ty.tuple [ Ty.path "usize"; Ty.path "usize" ] ].
      
      (*
          fn use_early_reject() -> bool {
              false
          }
      *)
      Definition use_early_reject (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [] => ltac:(M.monadic (Value.Bool false))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn rejecting(_a: usize, _b: usize) -> Self::Output {
              None
          }
      *)
      Definition rejecting (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ _a; _b ] =>
          ltac:(M.monadic
            (let _a := M.alloc (| _a |) in
            let _b := M.alloc (| _b |) in
            Value.StructTuple "core::option::Option::None" []))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn matching(a: usize, b: usize) -> Self::Output {
              Some((a, b))
          }
      *)
      Definition matching (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ a; b ] =>
          ltac:(M.monadic
            (let a := M.alloc (| a |) in
            let b := M.alloc (| b |) in
            Value.StructTuple
              "core::option::Option::Some"
              [ Value.Tuple [ M.read (| a |); M.read (| b |) ] ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::TwoWayStrategy"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Output", InstanceField.Ty _Output);
            ("use_early_reject", InstanceField.Method use_early_reject);
            ("rejecting", InstanceField.Method rejecting);
            ("matching", InstanceField.Method matching)
          ].
    End Impl_core_str_pattern_TwoWayStrategy_for_core_str_pattern_MatchOnly.
    
    (*
    Enum RejectAndMatch
    {
      const_params := [];
      ty_params := [];
      variants := [];
    }
    *)
    
    Module Impl_core_str_pattern_TwoWayStrategy_for_core_str_pattern_RejectAndMatch.
      Definition Self : Ty.t := Ty.path "core::str::pattern::RejectAndMatch".
      
      (*     type Output = SearchStep; *)
      Definition _Output : Ty.t := Ty.path "core::str::pattern::SearchStep".
      
      (*
          fn use_early_reject() -> bool {
              true
          }
      *)
      Definition use_early_reject (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [] => ltac:(M.monadic (Value.Bool true))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn rejecting(a: usize, b: usize) -> Self::Output {
              SearchStep::Reject(a, b)
          }
      *)
      Definition rejecting (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ a; b ] =>
          ltac:(M.monadic
            (let a := M.alloc (| a |) in
            let b := M.alloc (| b |) in
            Value.StructTuple
              "core::str::pattern::SearchStep::Reject"
              [ M.read (| a |); M.read (| b |) ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn matching(a: usize, b: usize) -> Self::Output {
              SearchStep::Match(a, b)
          }
      *)
      Definition matching (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ a; b ] =>
          ltac:(M.monadic
            (let a := M.alloc (| a |) in
            let b := M.alloc (| b |) in
            Value.StructTuple
              "core::str::pattern::SearchStep::Match"
              [ M.read (| a |); M.read (| b |) ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::str::pattern::TwoWayStrategy"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Output", InstanceField.Ty _Output);
            ("use_early_reject", InstanceField.Method use_early_reject);
            ("rejecting", InstanceField.Method rejecting);
            ("matching", InstanceField.Method matching)
          ].
    End Impl_core_str_pattern_TwoWayStrategy_for_core_str_pattern_RejectAndMatch.
    
    (*
    fn simd_contains(needle: &str, haystack: &str) -> Option<bool> {
        let needle = needle.as_bytes();
        let haystack = haystack.as_bytes();
    
        debug_assert!(needle.len() > 1);
    
        use crate::ops::BitAnd;
        use crate::simd::cmp::SimdPartialEq;
        use crate::simd::{mask8x16 as Mask, u8x16 as Block};
    
        let first_probe = needle[0];
        let last_byte_offset = needle.len() - 1;
    
        // the offset used for the 2nd vector
        let second_probe_offset = if needle.len() == 2 {
            // never bail out on len=2 needles because the probes will fully cover them and have
            // no degenerate cases.
            1
        } else {
            // try a few bytes in case first and last byte of the needle are the same
            let Some(second_probe_offset) =
                (needle.len().saturating_sub(4)..needle.len()).rfind(|&idx| needle[idx] != first_probe)
            else {
                // fall back to other search methods if we can't find any different bytes
                // since we could otherwise hit some degenerate cases
                return None;
            };
            second_probe_offset
        };
    
        // do a naive search if the haystack is too small to fit
        if haystack.len() < Block::LEN + last_byte_offset {
            return Some(haystack.windows(needle.len()).any(|c| c == needle));
        }
    
        let first_probe: Block = Block::splat(first_probe);
        let second_probe: Block = Block::splat(needle[second_probe_offset]);
        // first byte are already checked by the outer loop. to verify a match only the
        // remainder has to be compared.
        let trimmed_needle = &needle[1..];
    
        // this #[cold] is load-bearing, benchmark before removing it...
        let check_mask = #[cold]
        |idx, mask: u16, skip: bool| -> bool {
            if skip {
                return false;
            }
    
            // and so is this. optimizations are weird.
            let mut mask = mask;
    
            while mask != 0 {
                let trailing = mask.trailing_zeros();
                let offset = idx + trailing as usize + 1;
                // SAFETY: mask is between 0 and 15 trailing zeroes, we skip one additional byte that was already compared
                // and then take trimmed_needle.len() bytes. This is within the bounds defined by the outer loop
                unsafe {
                    let sub = haystack.get_unchecked(offset..).get_unchecked(..trimmed_needle.len());
                    if small_slice_eq(sub, trimmed_needle) {
                        return true;
                    }
                }
                mask &= !(1 << trailing);
            }
            false
        };
    
        let test_chunk = |idx| -> u16 {
            // SAFETY: this requires at least LANES bytes being readable at idx
            // that is ensured by the loop ranges (see comments below)
            let a: Block = unsafe { haystack.as_ptr().add(idx).cast::<Block>().read_unaligned() };
            // SAFETY: this requires LANES + block_offset bytes being readable at idx
            let b: Block = unsafe {
                haystack.as_ptr().add(idx).add(second_probe_offset).cast::<Block>().read_unaligned()
            };
            let eq_first: Mask = a.simd_eq(first_probe);
            let eq_last: Mask = b.simd_eq(second_probe);
            let both = eq_first.bitand(eq_last);
            let mask = both.to_bitmask() as u16;
    
            mask
        };
    
        let mut i = 0;
        let mut result = false;
        // The loop condition must ensure that there's enough headroom to read LANE bytes,
        // and not only at the current index but also at the index shifted by block_offset
        const UNROLL: usize = 4;
        while i + last_byte_offset + UNROLL * Block::LEN < haystack.len() && !result {
            let mut masks = [0u16; UNROLL];
            for j in 0..UNROLL {
                masks[j] = test_chunk(i + j * Block::LEN);
            }
            for j in 0..UNROLL {
                let mask = masks[j];
                if mask != 0 {
                    result |= check_mask(i + j * Block::LEN, mask, result);
                }
            }
            i += UNROLL * Block::LEN;
        }
        while i + last_byte_offset + Block::LEN < haystack.len() && !result {
            let mask = test_chunk(i);
            if mask != 0 {
                result |= check_mask(i, mask, result);
            }
            i += Block::LEN;
        }
    
        // Process the tail that didn't fit into LANES-sized steps.
        // This simply repeats the same procedure but as right-aligned chunk instead
        // of a left-aligned one. The last byte must be exactly flush with the string end so
        // we don't miss a single byte or read out of bounds.
        let i = haystack.len() - last_byte_offset - Block::LEN;
        let mask = test_chunk(i);
        if mask != 0 {
            result |= check_mask(i, mask, result);
        }
    
        Some(result)
    }
    *)
    Definition simd_contains (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ needle; haystack ] =>
        ltac:(M.monadic
          (let needle := M.alloc (| needle |) in
          let haystack := M.alloc (| haystack |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ needle :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| needle |) ]
                    |)
                  |) in
                let~ haystack :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "str", "as_bytes", [] |),
                      [ M.read (| haystack |) ]
                    |)
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.use (M.alloc (| Value.Bool true |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          UnOp.not (|
                                            BinOp.gt (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                                  "len",
                                                  []
                                                |),
                                                [ M.read (| needle |) ]
                                              |),
                                              Value.Integer IntegerKind.Usize 1
                                            |)
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.call_closure (|
                                          M.get_function (| "core::panicking::panic", [] |),
                                          [
                                            M.read (|
                                              Value.String "assertion failed: needle.len() > 1"
                                            |)
                                          ]
                                        |)
                                      |)
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ first_probe :=
                  M.copy (|
                    M.SubPointer.get_array_field (|
                      M.read (| needle |),
                      M.alloc (| Value.Integer IntegerKind.Usize 0 |)
                    |)
                  |) in
                let~ last_byte_offset :=
                  M.alloc (|
                    BinOp.Wrap.sub (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                          "len",
                          []
                        |),
                        [ M.read (| needle |) ]
                      |),
                      Value.Integer IntegerKind.Usize 1
                    |)
                  |) in
                let~ second_probe_offset :=
                  M.copy (|
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                        "len",
                                        []
                                      |),
                                      [ M.read (| needle |) ]
                                    |),
                                    Value.Integer IntegerKind.Usize 2
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (| Value.Integer IntegerKind.Usize 1 |)));
                        fun γ =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::iter::traits::double_ended::DoubleEndedIterator",
                                    Ty.apply
                                      (Ty.path "core::ops::range::Range")
                                      []
                                      [ Ty.path "usize" ],
                                    [],
                                    "rfind",
                                    [
                                      Ty.function
                                        [ Ty.tuple [ Ty.apply (Ty.path "&") [] [ Ty.path "usize" ] ]
                                        ]
                                        (Ty.path "bool")
                                    ]
                                  |),
                                  [
                                    M.alloc (|
                                      Value.StructRecord
                                        "core::ops::range::Range"
                                        [
                                          ("start",
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "usize",
                                                "saturating_sub",
                                                []
                                              |),
                                              [
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                                    "len",
                                                    []
                                                  |),
                                                  [ M.read (| needle |) ]
                                                |);
                                                Value.Integer IntegerKind.Usize 4
                                              ]
                                            |));
                                          ("end_",
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                                "len",
                                                []
                                              |),
                                              [ M.read (| needle |) ]
                                            |))
                                        ]
                                    |);
                                    M.closure
                                      (fun γ =>
                                        ltac:(M.monadic
                                          match γ with
                                          | [ α0 ] =>
                                            ltac:(M.monadic
                                              (M.match_operator (|
                                                M.alloc (| α0 |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ := M.read (| γ |) in
                                                      let idx := M.copy (| γ |) in
                                                      BinOp.ne (|
                                                        M.read (|
                                                          M.SubPointer.get_array_field (|
                                                            M.read (| needle |),
                                                            idx
                                                          |)
                                                        |),
                                                        M.read (| first_probe |)
                                                      |)))
                                                ]
                                              |)))
                                          | _ => M.impossible "wrong number of arguments"
                                          end))
                                  ]
                                |)
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::option::Option::Some",
                                        0
                                      |) in
                                    let second_probe_offset := M.copy (| γ0_0 |) in
                                    second_probe_offset))
                              ]
                            |)))
                      ]
                    |)
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| haystack |) ]
                                  |),
                                  BinOp.Wrap.add (|
                                    M.read (|
                                      M.get_constant (| "core::core_simd::vector::LEN" |)
                                    |),
                                    M.read (| last_byte_offset |)
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                M.return_ (|
                                  Value.StructTuple
                                    "core::option::Option::Some"
                                    [
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::iter::traits::iterator::Iterator",
                                          Ty.apply
                                            (Ty.path "core::slice::iter::Windows")
                                            []
                                            [ Ty.path "u8" ],
                                          [],
                                          "any",
                                          [
                                            Ty.function
                                              [
                                                Ty.tuple
                                                  [
                                                    Ty.apply
                                                      (Ty.path "&")
                                                      []
                                                      [
                                                        Ty.apply
                                                          (Ty.path "slice")
                                                          []
                                                          [ Ty.path "u8" ]
                                                      ]
                                                  ]
                                              ]
                                              (Ty.path "bool")
                                          ]
                                        |),
                                        [
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                                "windows",
                                                []
                                              |),
                                              [
                                                M.read (| haystack |);
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                                    "len",
                                                    []
                                                  |),
                                                  [ M.read (| needle |) ]
                                                |)
                                              ]
                                            |)
                                          |);
                                          M.closure
                                            (fun γ =>
                                              ltac:(M.monadic
                                                match γ with
                                                | [ α0 ] =>
                                                  ltac:(M.monadic
                                                    (M.match_operator (|
                                                      M.alloc (| α0 |),
                                                      [
                                                        fun γ =>
                                                          ltac:(M.monadic
                                                            (let c := M.copy (| γ |) in
                                                            M.call_closure (|
                                                              M.get_trait_method (|
                                                                "core::cmp::PartialEq",
                                                                Ty.apply
                                                                  (Ty.path "&")
                                                                  []
                                                                  [
                                                                    Ty.apply
                                                                      (Ty.path "slice")
                                                                      []
                                                                      [ Ty.path "u8" ]
                                                                  ],
                                                                [
                                                                  Ty.apply
                                                                    (Ty.path "&")
                                                                    []
                                                                    [
                                                                      Ty.apply
                                                                        (Ty.path "slice")
                                                                        []
                                                                        [ Ty.path "u8" ]
                                                                    ]
                                                                ],
                                                                "eq",
                                                                []
                                                              |),
                                                              [ c; needle ]
                                                            |)))
                                                      ]
                                                    |)))
                                                | _ => M.impossible "wrong number of arguments"
                                                end))
                                        ]
                                      |)
                                    ]
                                |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ first_probe :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply
                          (Ty.path "core::core_simd::vector::Simd")
                          [ Value.Integer IntegerKind.Usize 16 ]
                          [ Ty.path "u8" ],
                        "splat",
                        []
                      |),
                      [ M.read (| first_probe |) ]
                    |)
                  |) in
                let~ second_probe :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply
                          (Ty.path "core::core_simd::vector::Simd")
                          [ Value.Integer IntegerKind.Usize 16 ]
                          [ Ty.path "u8" ],
                        "splat",
                        []
                      |),
                      [
                        M.read (|
                          M.SubPointer.get_array_field (|
                            M.read (| needle |),
                            second_probe_offset
                          |)
                        |)
                      ]
                    |)
                  |) in
                let~ trimmed_needle :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::ops::index::Index",
                        Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                        [ Ty.apply (Ty.path "core::ops::range::RangeFrom") [] [ Ty.path "usize" ] ],
                        "index",
                        []
                      |),
                      [
                        M.read (| needle |);
                        Value.StructRecord
                          "core::ops::range::RangeFrom"
                          [ ("start", Value.Integer IntegerKind.Usize 1) ]
                      ]
                    |)
                  |) in
                let~ check_mask :=
                  M.alloc (|
                    M.closure
                      (fun γ =>
                        ltac:(M.monadic
                          match γ with
                          | [ α0; α1; α2 ] =>
                            ltac:(M.monadic
                              (M.match_operator (|
                                M.alloc (| α0 |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let idx := M.copy (| γ |) in
                                      M.match_operator (|
                                        M.alloc (| α1 |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let mask := M.copy (| γ |) in
                                              M.match_operator (|
                                                M.alloc (| α2 |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let skip := M.copy (| γ |) in
                                                      M.read (|
                                                        let~ _ :=
                                                          M.match_operator (|
                                                            M.alloc (| Value.Tuple [] |),
                                                            [
                                                              fun γ =>
                                                                ltac:(M.monadic
                                                                  (let γ := M.use skip in
                                                                  let _ :=
                                                                    M.is_constant_or_break_match (|
                                                                      M.read (| γ |),
                                                                      Value.Bool true
                                                                    |) in
                                                                  M.alloc (|
                                                                    M.never_to_any (|
                                                                      M.read (|
                                                                        M.return_ (|
                                                                          Value.Bool false
                                                                        |)
                                                                      |)
                                                                    |)
                                                                  |)));
                                                              fun γ =>
                                                                ltac:(M.monadic
                                                                  (M.alloc (| Value.Tuple [] |)))
                                                            ]
                                                          |) in
                                                        let~ mask := M.copy (| mask |) in
                                                        let~ _ :=
                                                          M.loop (|
                                                            ltac:(M.monadic
                                                              (M.match_operator (|
                                                                M.alloc (| Value.Tuple [] |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let γ :=
                                                                        M.use
                                                                          (M.alloc (|
                                                                            BinOp.ne (|
                                                                              M.read (| mask |),
                                                                              Value.Integer
                                                                                IntegerKind.U16
                                                                                0
                                                                            |)
                                                                          |)) in
                                                                      let _ :=
                                                                        M.is_constant_or_break_match (|
                                                                          M.read (| γ |),
                                                                          Value.Bool true
                                                                        |) in
                                                                      let~ trailing :=
                                                                        M.alloc (|
                                                                          M.call_closure (|
                                                                            M.get_associated_function (|
                                                                              Ty.path "u16",
                                                                              "trailing_zeros",
                                                                              []
                                                                            |),
                                                                            [ M.read (| mask |) ]
                                                                          |)
                                                                        |) in
                                                                      let~ offset :=
                                                                        M.alloc (|
                                                                          BinOp.Wrap.add (|
                                                                            BinOp.Wrap.add (|
                                                                              M.read (| idx |),
                                                                              M.rust_cast
                                                                                (M.read (|
                                                                                  trailing
                                                                                |))
                                                                            |),
                                                                            Value.Integer
                                                                              IntegerKind.Usize
                                                                              1
                                                                          |)
                                                                        |) in
                                                                      let~ _ :=
                                                                        let~ sub :=
                                                                          M.alloc (|
                                                                            M.call_closure (|
                                                                              M.get_associated_function (|
                                                                                Ty.apply
                                                                                  (Ty.path "slice")
                                                                                  []
                                                                                  [ Ty.path "u8" ],
                                                                                "get_unchecked",
                                                                                [
                                                                                  Ty.apply
                                                                                    (Ty.path
                                                                                      "core::ops::range::RangeTo")
                                                                                    []
                                                                                    [
                                                                                      Ty.path
                                                                                        "usize"
                                                                                    ]
                                                                                ]
                                                                              |),
                                                                              [
                                                                                M.call_closure (|
                                                                                  M.get_associated_function (|
                                                                                    Ty.apply
                                                                                      (Ty.path
                                                                                        "slice")
                                                                                      []
                                                                                      [ Ty.path "u8"
                                                                                      ],
                                                                                    "get_unchecked",
                                                                                    [
                                                                                      Ty.apply
                                                                                        (Ty.path
                                                                                          "core::ops::range::RangeFrom")
                                                                                        []
                                                                                        [
                                                                                          Ty.path
                                                                                            "usize"
                                                                                        ]
                                                                                    ]
                                                                                  |),
                                                                                  [
                                                                                    M.read (|
                                                                                      haystack
                                                                                    |);
                                                                                    Value.StructRecord
                                                                                      "core::ops::range::RangeFrom"
                                                                                      [
                                                                                        ("start",
                                                                                          M.read (|
                                                                                            offset
                                                                                          |))
                                                                                      ]
                                                                                  ]
                                                                                |);
                                                                                Value.StructRecord
                                                                                  "core::ops::range::RangeTo"
                                                                                  [
                                                                                    ("end_",
                                                                                      M.call_closure (|
                                                                                        M.get_associated_function (|
                                                                                          Ty.apply
                                                                                            (Ty.path
                                                                                              "slice")
                                                                                            []
                                                                                            [
                                                                                              Ty.path
                                                                                                "u8"
                                                                                            ],
                                                                                          "len",
                                                                                          []
                                                                                        |),
                                                                                        [
                                                                                          M.read (|
                                                                                            trimmed_needle
                                                                                          |)
                                                                                        ]
                                                                                      |))
                                                                                  ]
                                                                              ]
                                                                            |)
                                                                          |) in
                                                                        M.match_operator (|
                                                                          M.alloc (|
                                                                            Value.Tuple []
                                                                          |),
                                                                          [
                                                                            fun γ =>
                                                                              ltac:(M.monadic
                                                                                (let γ :=
                                                                                  M.use
                                                                                    (M.alloc (|
                                                                                      M.call_closure (|
                                                                                        M.get_function (|
                                                                                          "core::str::pattern::small_slice_eq",
                                                                                          []
                                                                                        |),
                                                                                        [
                                                                                          M.read (|
                                                                                            sub
                                                                                          |);
                                                                                          M.read (|
                                                                                            trimmed_needle
                                                                                          |)
                                                                                        ]
                                                                                      |)
                                                                                    |)) in
                                                                                let _ :=
                                                                                  M.is_constant_or_break_match (|
                                                                                    M.read (| γ |),
                                                                                    Value.Bool true
                                                                                  |) in
                                                                                M.alloc (|
                                                                                  M.never_to_any (|
                                                                                    M.read (|
                                                                                      M.return_ (|
                                                                                        Value.Bool
                                                                                          true
                                                                                      |)
                                                                                    |)
                                                                                  |)
                                                                                |)));
                                                                            fun γ =>
                                                                              ltac:(M.monadic
                                                                                (M.alloc (|
                                                                                  Value.Tuple []
                                                                                |)))
                                                                          ]
                                                                        |) in
                                                                      let~ _ :=
                                                                        let β := mask in
                                                                        M.write (|
                                                                          β,
                                                                          BinOp.bit_and
                                                                            (M.read (| β |))
                                                                            (UnOp.not (|
                                                                              BinOp.Wrap.shl (|
                                                                                Value.Integer
                                                                                  IntegerKind.U16
                                                                                  1,
                                                                                M.read (|
                                                                                  trailing
                                                                                |)
                                                                              |)
                                                                            |))
                                                                        |) in
                                                                      M.alloc (|
                                                                        Value.Tuple []
                                                                      |)));
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (M.alloc (|
                                                                        M.never_to_any (|
                                                                          M.read (|
                                                                            let~ _ :=
                                                                              M.alloc (|
                                                                                M.never_to_any (|
                                                                                  M.read (|
                                                                                    M.break (||)
                                                                                  |)
                                                                                |)
                                                                              |) in
                                                                            M.alloc (|
                                                                              Value.Tuple []
                                                                            |)
                                                                          |)
                                                                        |)
                                                                      |)))
                                                                ]
                                                              |)))
                                                          |) in
                                                        M.alloc (| Value.Bool false |)
                                                      |)))
                                                ]
                                              |)))
                                        ]
                                      |)))
                                ]
                              |)))
                          | _ => M.impossible "wrong number of arguments"
                          end))
                  |) in
                let~ test_chunk :=
                  M.alloc (|
                    M.closure
                      (fun γ =>
                        ltac:(M.monadic
                          match γ with
                          | [ α0 ] =>
                            ltac:(M.monadic
                              (M.match_operator (|
                                M.alloc (| α0 |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let idx := M.copy (| γ |) in
                                      M.read (|
                                        let~ a :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.apply
                                                  (Ty.path "*const")
                                                  []
                                                  [
                                                    Ty.apply
                                                      (Ty.path "core::core_simd::vector::Simd")
                                                      [ Value.Integer IntegerKind.Usize 16 ]
                                                      [ Ty.path "u8" ]
                                                  ],
                                                "read_unaligned",
                                                []
                                              |),
                                              [
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply (Ty.path "*const") [] [ Ty.path "u8" ],
                                                    "cast",
                                                    [
                                                      Ty.apply
                                                        (Ty.path "core::core_simd::vector::Simd")
                                                        [ Value.Integer IntegerKind.Usize 16 ]
                                                        [ Ty.path "u8" ]
                                                    ]
                                                  |),
                                                  [
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.apply
                                                          (Ty.path "*const")
                                                          []
                                                          [ Ty.path "u8" ],
                                                        "add",
                                                        []
                                                      |),
                                                      [
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.apply
                                                              (Ty.path "slice")
                                                              []
                                                              [ Ty.path "u8" ],
                                                            "as_ptr",
                                                            []
                                                          |),
                                                          [ M.read (| haystack |) ]
                                                        |);
                                                        M.read (| idx |)
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              ]
                                            |)
                                          |) in
                                        let~ b :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.apply
                                                  (Ty.path "*const")
                                                  []
                                                  [
                                                    Ty.apply
                                                      (Ty.path "core::core_simd::vector::Simd")
                                                      [ Value.Integer IntegerKind.Usize 16 ]
                                                      [ Ty.path "u8" ]
                                                  ],
                                                "read_unaligned",
                                                []
                                              |),
                                              [
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply (Ty.path "*const") [] [ Ty.path "u8" ],
                                                    "cast",
                                                    [
                                                      Ty.apply
                                                        (Ty.path "core::core_simd::vector::Simd")
                                                        [ Value.Integer IntegerKind.Usize 16 ]
                                                        [ Ty.path "u8" ]
                                                    ]
                                                  |),
                                                  [
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.apply
                                                          (Ty.path "*const")
                                                          []
                                                          [ Ty.path "u8" ],
                                                        "add",
                                                        []
                                                      |),
                                                      [
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.apply
                                                              (Ty.path "*const")
                                                              []
                                                              [ Ty.path "u8" ],
                                                            "add",
                                                            []
                                                          |),
                                                          [
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.apply
                                                                  (Ty.path "slice")
                                                                  []
                                                                  [ Ty.path "u8" ],
                                                                "as_ptr",
                                                                []
                                                              |),
                                                              [ M.read (| haystack |) ]
                                                            |);
                                                            M.read (| idx |)
                                                          ]
                                                        |);
                                                        M.read (| second_probe_offset |)
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              ]
                                            |)
                                          |) in
                                        let~ eq_first :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::core_simd::simd::cmp::eq::SimdPartialEq",
                                                Ty.apply
                                                  (Ty.path "core::core_simd::vector::Simd")
                                                  [ Value.Integer IntegerKind.Usize 16 ]
                                                  [ Ty.path "u8" ],
                                                [],
                                                "simd_eq",
                                                []
                                              |),
                                              [ M.read (| a |); M.read (| first_probe |) ]
                                            |)
                                          |) in
                                        let~ eq_last :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::core_simd::simd::cmp::eq::SimdPartialEq",
                                                Ty.apply
                                                  (Ty.path "core::core_simd::vector::Simd")
                                                  [ Value.Integer IntegerKind.Usize 16 ]
                                                  [ Ty.path "u8" ],
                                                [],
                                                "simd_eq",
                                                []
                                              |),
                                              [ M.read (| b |); M.read (| second_probe |) ]
                                            |)
                                          |) in
                                        let~ both :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::ops::bit::BitAnd",
                                                Ty.apply
                                                  (Ty.path "core::core_simd::masks::Mask")
                                                  [ Value.Integer IntegerKind.Usize 16 ]
                                                  [ Ty.path "i8" ],
                                                [
                                                  Ty.apply
                                                    (Ty.path "core::core_simd::masks::Mask")
                                                    [ Value.Integer IntegerKind.Usize 16 ]
                                                    [ Ty.path "i8" ]
                                                ],
                                                "bitand",
                                                []
                                              |),
                                              [ M.read (| eq_first |); M.read (| eq_last |) ]
                                            |)
                                          |) in
                                        let~ mask :=
                                          M.alloc (|
                                            M.rust_cast
                                              (M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.apply
                                                    (Ty.path "core::core_simd::masks::Mask")
                                                    [ Value.Integer IntegerKind.Usize 16 ]
                                                    [ Ty.path "i8" ],
                                                  "to_bitmask",
                                                  []
                                                |),
                                                [ M.read (| both |) ]
                                              |))
                                          |) in
                                        mask
                                      |)))
                                ]
                              |)))
                          | _ => M.impossible "wrong number of arguments"
                          end))
                  |) in
                let~ i := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
                let~ result := M.alloc (| Value.Bool false |) in
                let~ _ :=
                  M.loop (|
                    ltac:(M.monadic
                      (M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    LogicalOp.and (|
                                      BinOp.lt (|
                                        BinOp.Wrap.add (|
                                          BinOp.Wrap.add (|
                                            M.read (| i |),
                                            M.read (| last_byte_offset |)
                                          |),
                                          BinOp.Wrap.mul (|
                                            M.read (|
                                              M.get_constant (|
                                                "core::str::pattern::simd_contains::UNROLL"
                                              |)
                                            |),
                                            M.read (|
                                              M.get_constant (| "core::core_simd::vector::LEN" |)
                                            |)
                                          |)
                                        |),
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                            "len",
                                            []
                                          |),
                                          [ M.read (| haystack |) ]
                                        |)
                                      |),
                                      ltac:(M.monadic (UnOp.not (| M.read (| result |) |)))
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              let~ masks :=
                                M.alloc (|
                                  repeat (|
                                    Value.Integer IntegerKind.U16 0,
                                    Value.Integer IntegerKind.Usize 4
                                  |)
                                |) in
                              let~ _ :=
                                M.use
                                  (M.match_operator (|
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::iter::traits::collect::IntoIterator",
                                          Ty.apply
                                            (Ty.path "core::ops::range::Range")
                                            []
                                            [ Ty.path "usize" ],
                                          [],
                                          "into_iter",
                                          []
                                        |),
                                        [
                                          Value.StructRecord
                                            "core::ops::range::Range"
                                            [
                                              ("start", Value.Integer IntegerKind.Usize 0);
                                              ("end_",
                                                M.read (|
                                                  M.get_constant (|
                                                    "core::str::pattern::simd_contains::UNROLL"
                                                  |)
                                                |))
                                            ]
                                        ]
                                      |)
                                    |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let iter := M.copy (| γ |) in
                                          M.loop (|
                                            ltac:(M.monadic
                                              (let~ _ :=
                                                M.match_operator (|
                                                  M.alloc (|
                                                    M.call_closure (|
                                                      M.get_trait_method (|
                                                        "core::iter::traits::iterator::Iterator",
                                                        Ty.apply
                                                          (Ty.path "core::ops::range::Range")
                                                          []
                                                          [ Ty.path "usize" ],
                                                        [],
                                                        "next",
                                                        []
                                                      |),
                                                      [ iter ]
                                                    |)
                                                  |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let _ :=
                                                          M.is_struct_tuple (|
                                                            γ,
                                                            "core::option::Option::None"
                                                          |) in
                                                        M.alloc (|
                                                          M.never_to_any (|
                                                            M.read (| M.break (||) |)
                                                          |)
                                                        |)));
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ0_0 :=
                                                          M.SubPointer.get_struct_tuple_field (|
                                                            γ,
                                                            "core::option::Option::Some",
                                                            0
                                                          |) in
                                                        let j := M.copy (| γ0_0 |) in
                                                        let~ _ :=
                                                          M.write (|
                                                            M.SubPointer.get_array_field (|
                                                              masks,
                                                              j
                                                            |),
                                                            M.call_closure (|
                                                              M.get_trait_method (|
                                                                "core::ops::function::Fn",
                                                                Ty.function
                                                                  [ Ty.tuple [ Ty.path "usize" ] ]
                                                                  (Ty.path "u16"),
                                                                [ Ty.tuple [ Ty.path "usize" ] ],
                                                                "call",
                                                                []
                                                              |),
                                                              [
                                                                test_chunk;
                                                                Value.Tuple
                                                                  [
                                                                    BinOp.Wrap.add (|
                                                                      M.read (| i |),
                                                                      BinOp.Wrap.mul (|
                                                                        M.read (| j |),
                                                                        M.read (|
                                                                          M.get_constant (|
                                                                            "core::core_simd::vector::LEN"
                                                                          |)
                                                                        |)
                                                                      |)
                                                                    |)
                                                                  ]
                                                              ]
                                                            |)
                                                          |) in
                                                        M.alloc (| Value.Tuple [] |)))
                                                  ]
                                                |) in
                                              M.alloc (| Value.Tuple [] |)))
                                          |)))
                                    ]
                                  |)) in
                              let~ _ :=
                                M.use
                                  (M.match_operator (|
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::iter::traits::collect::IntoIterator",
                                          Ty.apply
                                            (Ty.path "core::ops::range::Range")
                                            []
                                            [ Ty.path "usize" ],
                                          [],
                                          "into_iter",
                                          []
                                        |),
                                        [
                                          Value.StructRecord
                                            "core::ops::range::Range"
                                            [
                                              ("start", Value.Integer IntegerKind.Usize 0);
                                              ("end_",
                                                M.read (|
                                                  M.get_constant (|
                                                    "core::str::pattern::simd_contains::UNROLL"
                                                  |)
                                                |))
                                            ]
                                        ]
                                      |)
                                    |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let iter := M.copy (| γ |) in
                                          M.loop (|
                                            ltac:(M.monadic
                                              (let~ _ :=
                                                M.match_operator (|
                                                  M.alloc (|
                                                    M.call_closure (|
                                                      M.get_trait_method (|
                                                        "core::iter::traits::iterator::Iterator",
                                                        Ty.apply
                                                          (Ty.path "core::ops::range::Range")
                                                          []
                                                          [ Ty.path "usize" ],
                                                        [],
                                                        "next",
                                                        []
                                                      |),
                                                      [ iter ]
                                                    |)
                                                  |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let _ :=
                                                          M.is_struct_tuple (|
                                                            γ,
                                                            "core::option::Option::None"
                                                          |) in
                                                        M.alloc (|
                                                          M.never_to_any (|
                                                            M.read (| M.break (||) |)
                                                          |)
                                                        |)));
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ0_0 :=
                                                          M.SubPointer.get_struct_tuple_field (|
                                                            γ,
                                                            "core::option::Option::Some",
                                                            0
                                                          |) in
                                                        let j := M.copy (| γ0_0 |) in
                                                        let~ mask :=
                                                          M.copy (|
                                                            M.SubPointer.get_array_field (|
                                                              masks,
                                                              j
                                                            |)
                                                          |) in
                                                        M.match_operator (|
                                                          M.alloc (| Value.Tuple [] |),
                                                          [
                                                            fun γ =>
                                                              ltac:(M.monadic
                                                                (let γ :=
                                                                  M.use
                                                                    (M.alloc (|
                                                                      BinOp.ne (|
                                                                        M.read (| mask |),
                                                                        Value.Integer
                                                                          IntegerKind.U16
                                                                          0
                                                                      |)
                                                                    |)) in
                                                                let _ :=
                                                                  M.is_constant_or_break_match (|
                                                                    M.read (| γ |),
                                                                    Value.Bool true
                                                                  |) in
                                                                let~ _ :=
                                                                  let β := result in
                                                                  M.write (|
                                                                    β,
                                                                    BinOp.bit_or
                                                                      (M.read (| β |))
                                                                      (M.call_closure (|
                                                                        M.get_trait_method (|
                                                                          "core::ops::function::Fn",
                                                                          Ty.function
                                                                            [
                                                                              Ty.tuple
                                                                                [
                                                                                  Ty.path "usize";
                                                                                  Ty.path "u16";
                                                                                  Ty.path "bool"
                                                                                ]
                                                                            ]
                                                                            (Ty.path "bool"),
                                                                          [
                                                                            Ty.tuple
                                                                              [
                                                                                Ty.path "usize";
                                                                                Ty.path "u16";
                                                                                Ty.path "bool"
                                                                              ]
                                                                          ],
                                                                          "call",
                                                                          []
                                                                        |),
                                                                        [
                                                                          check_mask;
                                                                          Value.Tuple
                                                                            [
                                                                              BinOp.Wrap.add (|
                                                                                M.read (| i |),
                                                                                BinOp.Wrap.mul (|
                                                                                  M.read (| j |),
                                                                                  M.read (|
                                                                                    M.get_constant (|
                                                                                      "core::core_simd::vector::LEN"
                                                                                    |)
                                                                                  |)
                                                                                |)
                                                                              |);
                                                                              M.read (| mask |);
                                                                              M.read (| result |)
                                                                            ]
                                                                        ]
                                                                      |))
                                                                  |) in
                                                                M.alloc (| Value.Tuple [] |)));
                                                            fun γ =>
                                                              ltac:(M.monadic
                                                                (M.alloc (| Value.Tuple [] |)))
                                                          ]
                                                        |)))
                                                  ]
                                                |) in
                                              M.alloc (| Value.Tuple [] |)))
                                          |)))
                                    ]
                                  |)) in
                              let~ _ :=
                                let β := i in
                                M.write (|
                                  β,
                                  BinOp.Wrap.add (|
                                    M.read (| β |),
                                    BinOp.Wrap.mul (|
                                      M.read (|
                                        M.get_constant (|
                                          "core::str::pattern::simd_contains::UNROLL"
                                        |)
                                      |),
                                      M.read (|
                                        M.get_constant (| "core::core_simd::vector::LEN" |)
                                      |)
                                    |)
                                  |)
                                |) in
                              M.alloc (| Value.Tuple [] |)));
                          fun γ =>
                            ltac:(M.monadic
                              (M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    let~ _ :=
                                      M.alloc (|
                                        M.never_to_any (| M.read (| M.break (||) |) |)
                                      |) in
                                    M.alloc (| Value.Tuple [] |)
                                  |)
                                |)
                              |)))
                        ]
                      |)))
                  |) in
                let~ _ :=
                  M.loop (|
                    ltac:(M.monadic
                      (M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    LogicalOp.and (|
                                      BinOp.lt (|
                                        BinOp.Wrap.add (|
                                          BinOp.Wrap.add (|
                                            M.read (| i |),
                                            M.read (| last_byte_offset |)
                                          |),
                                          M.read (|
                                            M.get_constant (| "core::core_simd::vector::LEN" |)
                                          |)
                                        |),
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                            "len",
                                            []
                                          |),
                                          [ M.read (| haystack |) ]
                                        |)
                                      |),
                                      ltac:(M.monadic (UnOp.not (| M.read (| result |) |)))
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              let~ mask :=
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::function::Fn",
                                      Ty.function [ Ty.tuple [ Ty.path "usize" ] ] (Ty.path "u16"),
                                      [ Ty.tuple [ Ty.path "usize" ] ],
                                      "call",
                                      []
                                    |),
                                    [ test_chunk; Value.Tuple [ M.read (| i |) ] ]
                                  |)
                                |) in
                              let~ _ :=
                                M.match_operator (|
                                  M.alloc (| Value.Tuple [] |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ :=
                                          M.use
                                            (M.alloc (|
                                              BinOp.ne (|
                                                M.read (| mask |),
                                                Value.Integer IntegerKind.U16 0
                                              |)
                                            |)) in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        let~ _ :=
                                          let β := result in
                                          M.write (|
                                            β,
                                            BinOp.bit_or
                                              (M.read (| β |))
                                              (M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::function::Fn",
                                                  Ty.function
                                                    [
                                                      Ty.tuple
                                                        [
                                                          Ty.path "usize";
                                                          Ty.path "u16";
                                                          Ty.path "bool"
                                                        ]
                                                    ]
                                                    (Ty.path "bool"),
                                                  [
                                                    Ty.tuple
                                                      [
                                                        Ty.path "usize";
                                                        Ty.path "u16";
                                                        Ty.path "bool"
                                                      ]
                                                  ],
                                                  "call",
                                                  []
                                                |),
                                                [
                                                  check_mask;
                                                  Value.Tuple
                                                    [
                                                      M.read (| i |);
                                                      M.read (| mask |);
                                                      M.read (| result |)
                                                    ]
                                                ]
                                              |))
                                          |) in
                                        M.alloc (| Value.Tuple [] |)));
                                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                  ]
                                |) in
                              let~ _ :=
                                let β := i in
                                M.write (|
                                  β,
                                  BinOp.Wrap.add (|
                                    M.read (| β |),
                                    M.read (| M.get_constant (| "core::core_simd::vector::LEN" |) |)
                                  |)
                                |) in
                              M.alloc (| Value.Tuple [] |)));
                          fun γ =>
                            ltac:(M.monadic
                              (M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    let~ _ :=
                                      M.alloc (|
                                        M.never_to_any (| M.read (| M.break (||) |) |)
                                      |) in
                                    M.alloc (| Value.Tuple [] |)
                                  |)
                                |)
                              |)))
                        ]
                      |)))
                  |) in
                let~ i :=
                  M.alloc (|
                    BinOp.Wrap.sub (|
                      BinOp.Wrap.sub (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                            "len",
                            []
                          |),
                          [ M.read (| haystack |) ]
                        |),
                        M.read (| last_byte_offset |)
                      |),
                      M.read (| M.get_constant (| "core::core_simd::vector::LEN" |) |)
                    |)
                  |) in
                let~ mask :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::ops::function::Fn",
                        Ty.function [ Ty.tuple [ Ty.path "usize" ] ] (Ty.path "u16"),
                        [ Ty.tuple [ Ty.path "usize" ] ],
                        "call",
                        []
                      |),
                      [ test_chunk; Value.Tuple [ M.read (| i |) ] ]
                    |)
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.ne (| M.read (| mask |), Value.Integer IntegerKind.U16 0 |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            let β := result in
                            M.write (|
                              β,
                              BinOp.bit_or
                                (M.read (| β |))
                                (M.call_closure (|
                                  M.get_trait_method (|
                                    "core::ops::function::Fn",
                                    Ty.function
                                      [ Ty.tuple [ Ty.path "usize"; Ty.path "u16"; Ty.path "bool" ]
                                      ]
                                      (Ty.path "bool"),
                                    [ Ty.tuple [ Ty.path "usize"; Ty.path "u16"; Ty.path "bool" ] ],
                                    "call",
                                    []
                                  |),
                                  [
                                    check_mask;
                                    Value.Tuple
                                      [ M.read (| i |); M.read (| mask |); M.read (| result |) ]
                                  ]
                                |))
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                M.alloc (| Value.StructTuple "core::option::Option::Some" [ M.read (| result |) ] |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_simd_contains : M.IsFunction "core::str::pattern::simd_contains" simd_contains.
    
    Module simd_contains.
      Definition value_UNROLL : Value.t :=
        M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.Usize 4 |))).
    End simd_contains.
    
    (*
    unsafe fn small_slice_eq(x: &[u8], y: &[u8]) -> bool {
        debug_assert_eq!(x.len(), y.len());
        // This function is adapted from
        // https://github.com/BurntSushi/memchr/blob/8037d11b4357b0f07be2bb66dc2659d9cf28ad32/src/memmem/util.rs#L32
    
        // If we don't have enough bytes to do 4-byte at a time loads, then
        // fall back to the naive slow version.
        //
        // Potential alternative: We could do a copy_nonoverlapping combined with a mask instead
        // of a loop. Benchmark it.
        if x.len() < 4 {
            for (&b1, &b2) in x.iter().zip(y) {
                if b1 != b2 {
                    return false;
                }
            }
            return true;
        }
        // When we have 4 or more bytes to compare, then proceed in chunks of 4 at
        // a time using unaligned loads.
        //
        // Also, why do 4 byte loads instead of, say, 8 byte loads? The reason is
        // that this particular version of memcmp is likely to be called with tiny
        // needles. That means that if we do 8 byte loads, then a higher proportion
        // of memcmp calls will use the slower variant above. With that said, this
        // is a hypothesis and is only loosely supported by benchmarks. There's
        // likely some improvement that could be made here. The main thing here
        // though is to optimize for latency, not throughput.
    
        // SAFETY: Via the conditional above, we know that both `px` and `py`
        // have the same length, so `px < pxend` implies that `py < pyend`.
        // Thus, dereferencing both `px` and `py` in the loop below is safe.
        //
        // Moreover, we set `pxend` and `pyend` to be 4 bytes before the actual
        // end of `px` and `py`. Thus, the final dereference outside of the
        // loop is guaranteed to be valid. (The final comparison will overlap with
        // the last comparison done in the loop for lengths that aren't multiples
        // of four.)
        //
        // Finally, we needn't worry about alignment here, since we do unaligned
        // loads.
        unsafe {
            let (mut px, mut py) = (x.as_ptr(), y.as_ptr());
            let (pxend, pyend) = (px.add(x.len() - 4), py.add(y.len() - 4));
            while px < pxend {
                let vx = (px as *const u32).read_unaligned();
                let vy = (py as *const u32).read_unaligned();
                if vx != vy {
                    return false;
                }
                px = px.add(4);
                py = py.add(4);
            }
            let vx = (pxend as *const u32).read_unaligned();
            let vy = (pyend as *const u32).read_unaligned();
            vx == vy
        }
    }
    *)
    Definition small_slice_eq (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ x; y ] =>
        ltac:(M.monadic
          (let x := M.alloc (| x |) in
          let y := M.alloc (| y |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.use (M.alloc (| Value.Bool true |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            M.match_operator (|
                              M.alloc (|
                                Value.Tuple
                                  [
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                          "len",
                                          []
                                        |),
                                        [ M.read (| x |) ]
                                      |)
                                    |);
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                          "len",
                                          []
                                        |),
                                        [ M.read (| y |) ]
                                      |)
                                    |)
                                  ]
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                    let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                    let left_val := M.copy (| γ0_0 |) in
                                    let right_val := M.copy (| γ0_1 |) in
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  UnOp.not (|
                                                    BinOp.eq (|
                                                      M.read (| M.read (| left_val |) |),
                                                      M.read (| M.read (| right_val |) |)
                                                    |)
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.alloc (|
                                              M.never_to_any (|
                                                M.read (|
                                                  let~ kind :=
                                                    M.alloc (|
                                                      Value.StructTuple
                                                        "core::panicking::AssertKind::Eq"
                                                        []
                                                    |) in
                                                  M.alloc (|
                                                    M.call_closure (|
                                                      M.get_function (|
                                                        "core::panicking::assert_failed",
                                                        [ Ty.path "usize"; Ty.path "usize" ]
                                                      |),
                                                      [
                                                        M.read (| kind |);
                                                        M.read (| left_val |);
                                                        M.read (| right_val |);
                                                        Value.StructTuple
                                                          "core::option::Option::None"
                                                          []
                                                      ]
                                                    |)
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)))
                              ]
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| x |) ]
                                  |),
                                  Value.Integer IntegerKind.Usize 4
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.use
                                    (M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::collect::IntoIterator",
                                            Ty.apply
                                              (Ty.path "core::iter::adapters::zip::Zip")
                                              []
                                              [
                                                Ty.apply
                                                  (Ty.path "core::slice::iter::Iter")
                                                  []
                                                  [ Ty.path "u8" ];
                                                Ty.apply
                                                  (Ty.path "core::slice::iter::Iter")
                                                  []
                                                  [ Ty.path "u8" ]
                                              ],
                                            [],
                                            "into_iter",
                                            []
                                          |),
                                          [
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::iter::traits::iterator::Iterator",
                                                Ty.apply
                                                  (Ty.path "core::slice::iter::Iter")
                                                  []
                                                  [ Ty.path "u8" ],
                                                [],
                                                "zip",
                                                [
                                                  Ty.apply
                                                    (Ty.path "&")
                                                    []
                                                    [ Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ]
                                                    ]
                                                ]
                                              |),
                                              [
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                                    "iter",
                                                    []
                                                  |),
                                                  [ M.read (| x |) ]
                                                |);
                                                M.read (| y |)
                                              ]
                                            |)
                                          ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let iter := M.copy (| γ |) in
                                            M.loop (|
                                              ltac:(M.monadic
                                                (let~ _ :=
                                                  M.match_operator (|
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_trait_method (|
                                                          "core::iter::traits::iterator::Iterator",
                                                          Ty.apply
                                                            (Ty.path
                                                              "core::iter::adapters::zip::Zip")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path "core::slice::iter::Iter")
                                                                []
                                                                [ Ty.path "u8" ];
                                                              Ty.apply
                                                                (Ty.path "core::slice::iter::Iter")
                                                                []
                                                                [ Ty.path "u8" ]
                                                            ],
                                                          [],
                                                          "next",
                                                          []
                                                        |),
                                                        [ iter ]
                                                      |)
                                                    |),
                                                    [
                                                      fun γ =>
                                                        ltac:(M.monadic
                                                          (let _ :=
                                                            M.is_struct_tuple (|
                                                              γ,
                                                              "core::option::Option::None"
                                                            |) in
                                                          M.alloc (|
                                                            M.never_to_any (|
                                                              M.read (| M.break (||) |)
                                                            |)
                                                          |)));
                                                      fun γ =>
                                                        ltac:(M.monadic
                                                          (let γ0_0 :=
                                                            M.SubPointer.get_struct_tuple_field (|
                                                              γ,
                                                              "core::option::Option::Some",
                                                              0
                                                            |) in
                                                          let γ1_0 :=
                                                            M.SubPointer.get_tuple_field (|
                                                              γ0_0,
                                                              0
                                                            |) in
                                                          let γ1_1 :=
                                                            M.SubPointer.get_tuple_field (|
                                                              γ0_0,
                                                              1
                                                            |) in
                                                          let γ1_0 := M.read (| γ1_0 |) in
                                                          let b1 := M.copy (| γ1_0 |) in
                                                          let γ1_1 := M.read (| γ1_1 |) in
                                                          let b2 := M.copy (| γ1_1 |) in
                                                          M.match_operator (|
                                                            M.alloc (| Value.Tuple [] |),
                                                            [
                                                              fun γ =>
                                                                ltac:(M.monadic
                                                                  (let γ :=
                                                                    M.use
                                                                      (M.alloc (|
                                                                        BinOp.ne (|
                                                                          M.read (| b1 |),
                                                                          M.read (| b2 |)
                                                                        |)
                                                                      |)) in
                                                                  let _ :=
                                                                    M.is_constant_or_break_match (|
                                                                      M.read (| γ |),
                                                                      Value.Bool true
                                                                    |) in
                                                                  M.alloc (|
                                                                    M.never_to_any (|
                                                                      M.read (|
                                                                        M.return_ (|
                                                                          Value.Bool false
                                                                        |)
                                                                      |)
                                                                    |)
                                                                  |)));
                                                              fun γ =>
                                                                ltac:(M.monadic
                                                                  (M.alloc (| Value.Tuple [] |)))
                                                            ]
                                                          |)))
                                                    ]
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)))
                                            |)))
                                      ]
                                    |)) in
                                M.return_ (| Value.Bool true |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                M.match_operator (|
                  M.alloc (|
                    Value.Tuple
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                            "as_ptr",
                            []
                          |),
                          [ M.read (| x |) ]
                        |);
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                            "as_ptr",
                            []
                          |),
                          [ M.read (| y |) ]
                        |)
                      ]
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                        let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                        let px := M.copy (| γ0_0 |) in
                        let py := M.copy (| γ0_1 |) in
                        M.match_operator (|
                          M.alloc (|
                            Value.Tuple
                              [
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "*const") [] [ Ty.path "u8" ],
                                    "add",
                                    []
                                  |),
                                  [
                                    M.read (| px |);
                                    BinOp.Wrap.sub (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                          "len",
                                          []
                                        |),
                                        [ M.read (| x |) ]
                                      |),
                                      Value.Integer IntegerKind.Usize 4
                                    |)
                                  ]
                                |);
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply (Ty.path "*const") [] [ Ty.path "u8" ],
                                    "add",
                                    []
                                  |),
                                  [
                                    M.read (| py |);
                                    BinOp.Wrap.sub (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                          "len",
                                          []
                                        |),
                                        [ M.read (| y |) ]
                                      |),
                                      Value.Integer IntegerKind.Usize 4
                                    |)
                                  ]
                                |)
                              ]
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                let pxend := M.copy (| γ0_0 |) in
                                let pyend := M.copy (| γ0_1 |) in
                                let~ _ :=
                                  M.loop (|
                                    ltac:(M.monadic
                                      (M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.use
                                                  (M.alloc (|
                                                    BinOp.lt (|
                                                      M.read (| px |),
                                                      M.read (| pxend |)
                                                    |)
                                                  |)) in
                                              let _ :=
                                                M.is_constant_or_break_match (|
                                                  M.read (| γ |),
                                                  Value.Bool true
                                                |) in
                                              let~ vx :=
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "*const")
                                                        []
                                                        [ Ty.path "u32" ],
                                                      "read_unaligned",
                                                      []
                                                    |),
                                                    [ M.rust_cast (M.read (| px |)) ]
                                                  |)
                                                |) in
                                              let~ vy :=
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "*const")
                                                        []
                                                        [ Ty.path "u32" ],
                                                      "read_unaligned",
                                                      []
                                                    |),
                                                    [ M.rust_cast (M.read (| py |)) ]
                                                  |)
                                                |) in
                                              let~ _ :=
                                                M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ :=
                                                          M.use
                                                            (M.alloc (|
                                                              BinOp.ne (|
                                                                M.read (| vx |),
                                                                M.read (| vy |)
                                                              |)
                                                            |)) in
                                                        let _ :=
                                                          M.is_constant_or_break_match (|
                                                            M.read (| γ |),
                                                            Value.Bool true
                                                          |) in
                                                        M.alloc (|
                                                          M.never_to_any (|
                                                            M.read (|
                                                              M.return_ (| Value.Bool false |)
                                                            |)
                                                          |)
                                                        |)));
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (M.alloc (| Value.Tuple [] |)))
                                                  ]
                                                |) in
                                              let~ _ :=
                                                M.write (|
                                                  px,
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "*const")
                                                        []
                                                        [ Ty.path "u8" ],
                                                      "add",
                                                      []
                                                    |),
                                                    [
                                                      M.read (| px |);
                                                      Value.Integer IntegerKind.Usize 4
                                                    ]
                                                  |)
                                                |) in
                                              let~ _ :=
                                                M.write (|
                                                  py,
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "*const")
                                                        []
                                                        [ Ty.path "u8" ],
                                                      "add",
                                                      []
                                                    |),
                                                    [
                                                      M.read (| py |);
                                                      Value.Integer IntegerKind.Usize 4
                                                    ]
                                                  |)
                                                |) in
                                              M.alloc (| Value.Tuple [] |)));
                                          fun γ =>
                                            ltac:(M.monadic
                                              (M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    let~ _ :=
                                                      M.alloc (|
                                                        M.never_to_any (|
                                                          M.read (| M.break (||) |)
                                                        |)
                                                      |) in
                                                    M.alloc (| Value.Tuple [] |)
                                                  |)
                                                |)
                                              |)))
                                        ]
                                      |)))
                                  |) in
                                let~ vx :=
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "*const") [] [ Ty.path "u32" ],
                                        "read_unaligned",
                                        []
                                      |),
                                      [ M.rust_cast (M.read (| pxend |)) ]
                                    |)
                                  |) in
                                let~ vy :=
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "*const") [] [ Ty.path "u32" ],
                                        "read_unaligned",
                                        []
                                      |),
                                      [ M.rust_cast (M.read (| pyend |)) ]
                                    |)
                                  |) in
                                M.alloc (| BinOp.eq (| M.read (| vx |), M.read (| vy |) |) |)))
                          ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_small_slice_eq :
      M.IsFunction "core::str::pattern::small_slice_eq" small_slice_eq.
  End pattern.
End str.
