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

Module interpreter.
  Module shared_memory.
    (* StructRecord
      {
        name := "SharedMemory";
        const_params := [];
        ty_params := [];
        fields :=
          [
            ("buffer",
              Ty.apply
                (Ty.path "alloc::vec::Vec")
                []
                [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ]);
            ("checkpoints",
              Ty.apply
                (Ty.path "alloc::vec::Vec")
                []
                [ Ty.path "usize"; Ty.path "alloc::alloc::Global" ]);
            ("last_checkpoint", Ty.path "usize")
          ];
      } *)
    
    Module Impl_core_clone_Clone_for_revm_interpreter_interpreter_shared_memory_SharedMemory.
      Definition Self : Ty.t :=
        Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory".
      
      (* 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
              "revm_interpreter::interpreter::shared_memory::SharedMemory"
              [
                ("buffer",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "buffer"
                      |)
                    ]
                  |));
                ("checkpoints",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "usize"; Ty.path "alloc::alloc::Global" ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "checkpoints"
                      |)
                    ]
                  |));
                ("last_checkpoint",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "last_checkpoint"
                      |)
                    ]
                  |))
              ]))
        | _, _, _ => 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_revm_interpreter_interpreter_shared_memory_SharedMemory.
    
    Module Impl_core_marker_StructuralPartialEq_for_revm_interpreter_interpreter_shared_memory_SharedMemory.
      Definition Self : Ty.t :=
        Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory".
      
      Axiom Implements :
        M.IsTraitInstance
          "core::marker::StructuralPartialEq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_StructuralPartialEq_for_revm_interpreter_interpreter_shared_memory_SharedMemory.
    
    Module Impl_core_cmp_PartialEq_for_revm_interpreter_interpreter_shared_memory_SharedMemory.
      Definition Self : Ty.t :=
        Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory".
      
      (* 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
            LogicalOp.and (|
              LogicalOp.and (|
                M.call_closure (|
                  M.get_trait_method (|
                    "core::cmp::PartialEq",
                    Ty.apply
                      (Ty.path "alloc::vec::Vec")
                      []
                      [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                    [
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ]
                    ],
                    "eq",
                    []
                  |),
                  [
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "revm_interpreter::interpreter::shared_memory::SharedMemory",
                      "buffer"
                    |);
                    M.SubPointer.get_struct_record_field (|
                      M.read (| other |),
                      "revm_interpreter::interpreter::shared_memory::SharedMemory",
                      "buffer"
                    |)
                  ]
                |),
                ltac:(M.monadic
                  (M.call_closure (|
                    M.get_trait_method (|
                      "core::cmp::PartialEq",
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "usize"; Ty.path "alloc::alloc::Global" ],
                      [
                        Ty.apply
                          (Ty.path "alloc::vec::Vec")
                          []
                          [ Ty.path "usize"; Ty.path "alloc::alloc::Global" ]
                      ],
                      "eq",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "checkpoints"
                      |);
                      M.SubPointer.get_struct_record_field (|
                        M.read (| other |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "checkpoints"
                      |)
                    ]
                  |)))
              |),
              ltac:(M.monadic
                (BinOp.eq (|
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "revm_interpreter::interpreter::shared_memory::SharedMemory",
                      "last_checkpoint"
                    |)
                  |),
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| other |),
                      "revm_interpreter::interpreter::shared_memory::SharedMemory",
                      "last_checkpoint"
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => 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_revm_interpreter_interpreter_shared_memory_SharedMemory.
    
    Module Impl_core_cmp_Eq_for_revm_interpreter_interpreter_shared_memory_SharedMemory.
      Definition Self : Ty.t :=
        Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory".
      
      (* 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.match_operator (|
                        Value.DeclaredButUndefined,
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (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_revm_interpreter_interpreter_shared_memory_SharedMemory.
    
    Module Impl_core_hash_Hash_for_revm_interpreter_interpreter_shared_memory_SharedMemory.
      Definition Self : Ty.t :=
        Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory".
      
      (* Hash *)
      Definition hash (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ __H ], [ self; state ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let state := M.alloc (| state |) in
            M.read (|
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::hash::Hash",
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                      [],
                      "hash",
                      [ __H ]
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "buffer"
                      |);
                      M.read (| state |)
                    ]
                  |)
                |) in
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::hash::Hash",
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "usize"; Ty.path "alloc::alloc::Global" ],
                      [],
                      "hash",
                      [ __H ]
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "checkpoints"
                      |);
                      M.read (| state |)
                    ]
                  |)
                |) in
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (| "core::hash::Hash", Ty.path "usize", [], "hash", [ __H ] |),
                  [
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "revm_interpreter::interpreter::shared_memory::SharedMemory",
                      "last_checkpoint"
                    |);
                    M.read (| state |)
                  ]
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::hash::Hash"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("hash", InstanceField.Method hash) ].
    End Impl_core_hash_Hash_for_revm_interpreter_interpreter_shared_memory_SharedMemory.
    
    Definition value_EMPTY_SHARED_MEMORY : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            Value.StructRecord
              "revm_interpreter::interpreter::shared_memory::SharedMemory"
              [
                ("buffer",
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                      "new",
                      []
                    |),
                    []
                  |));
                ("checkpoints",
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "usize"; Ty.path "alloc::alloc::Global" ],
                      "new",
                      []
                    |),
                    []
                  |));
                ("last_checkpoint", Value.Integer IntegerKind.Usize 0)
              ]
          |))).
    
    Module Impl_core_fmt_Debug_for_revm_interpreter_interpreter_shared_memory_SharedMemory.
      Definition Self : Ty.t :=
        Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory".
      
      (*
          fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
              f.debug_struct("SharedMemory")
                  .field("current_len", &self.len())
                  .field(
                      "context_memory",
                      &crate::primitives::hex::encode(self.context_memory()),
                  )
                  .finish_non_exhaustive()
          }
      *)
      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::builders::DebugStruct",
                "finish_non_exhaustive",
                []
              |),
              [
                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 "SharedMemory" |) ]
                          |)
                        |);
                        M.read (| Value.String "current_len" |);
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                              "len",
                              []
                            |),
                            [ M.read (| self |) ]
                          |)
                        |)
                      ]
                    |);
                    M.read (| Value.String "context_memory" |);
                    M.alloc (|
                      M.call_closure (|
                        M.get_function (|
                          "const_hex::encode",
                          [
                            Ty.apply
                              (Ty.path "&")
                              []
                              [ Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ] ]
                          ]
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                              "context_memory",
                              []
                            |),
                            [ M.read (| self |) ]
                          |)
                        ]
                      |)
                    |)
                  ]
                |)
              ]
            |)))
        | _, _, _ => 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_revm_interpreter_interpreter_shared_memory_SharedMemory.
    
    Module Impl_core_default_Default_for_revm_interpreter_interpreter_shared_memory_SharedMemory.
      Definition Self : Ty.t :=
        Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory".
      
      (*
          fn default() -> Self {
              Self::new()
          }
      *)
      Definition default (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [] =>
          ltac:(M.monadic
            (M.call_closure (|
              M.get_associated_function (|
                Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                "new",
                []
              |),
              []
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::default::Default"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("default", InstanceField.Method default) ].
    End Impl_core_default_Default_for_revm_interpreter_interpreter_shared_memory_SharedMemory.
    
    Module Impl_revm_interpreter_interpreter_shared_memory_SharedMemory.
      Definition Self : Ty.t :=
        Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory".
      
      (*
          pub fn new() -> Self {
              Self::with_capacity(4 * 1024) // from evmone
          }
      *)
      Definition new (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [] =>
          ltac:(M.monadic
            (M.call_closure (|
              M.get_associated_function (|
                Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                "with_capacity",
                []
              |),
              [
                BinOp.Wrap.mul (|
                  Value.Integer IntegerKind.Usize 4,
                  Value.Integer IntegerKind.Usize 1024
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_new : M.IsAssociatedFunction Self "new" new.
      
      (*
          pub fn with_capacity(capacity: usize) -> Self {
              Self {
                  buffer: Vec::with_capacity(capacity),
                  checkpoints: Vec::with_capacity(32),
                  last_checkpoint: 0,
                  #[cfg(feature = "memory_limit")]
                  memory_limit: u64::MAX,
              }
          }
      *)
      Definition with_capacity (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ capacity ] =>
          ltac:(M.monadic
            (let capacity := M.alloc (| capacity |) in
            Value.StructRecord
              "revm_interpreter::interpreter::shared_memory::SharedMemory"
              [
                ("buffer",
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                      "with_capacity",
                      []
                    |),
                    [ M.read (| capacity |) ]
                  |));
                ("checkpoints",
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "usize"; Ty.path "alloc::alloc::Global" ],
                      "with_capacity",
                      []
                    |),
                    [ Value.Integer IntegerKind.Usize 32 ]
                  |));
                ("last_checkpoint", Value.Integer IntegerKind.Usize 0)
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_with_capacity :
        M.IsAssociatedFunction Self "with_capacity" with_capacity.
      
      (*
          pub fn new_context(&mut self) {
              let new_checkpoint = self.buffer.len();
              self.checkpoints.push(new_checkpoint);
              self.last_checkpoint = new_checkpoint;
          }
      *)
      Definition new_context (ε : 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~ new_checkpoint :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                      "len",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "buffer"
                      |)
                    ]
                  |)
                |) in
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "usize"; Ty.path "alloc::alloc::Global" ],
                      "push",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "checkpoints"
                      |);
                      M.read (| new_checkpoint |)
                    ]
                  |)
                |) in
              let~ _ :=
                M.write (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "revm_interpreter::interpreter::shared_memory::SharedMemory",
                    "last_checkpoint"
                  |),
                  M.read (| new_checkpoint |)
                |) in
              M.alloc (| Value.Tuple [] |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_new_context : M.IsAssociatedFunction Self "new_context" new_context.
      
      (*
          pub fn free_context(&mut self) {
              if let Some(old_checkpoint) = self.checkpoints.pop() {
                  self.last_checkpoint = self.checkpoints.last().cloned().unwrap_or_default();
                  // SAFETY: buffer length is less than or equal `old_checkpoint`
                  unsafe { self.buffer.set_len(old_checkpoint) };
              }
          }
      *)
      Definition free_context (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "alloc::vec::Vec")
                                []
                                [ Ty.path "usize"; Ty.path "alloc::alloc::Global" ],
                              "pop",
                              []
                            |),
                            [
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "revm_interpreter::interpreter::shared_memory::SharedMemory",
                                "checkpoints"
                              |)
                            ]
                          |)
                        |) in
                      let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::option::Option::Some",
                          0
                        |) in
                      let old_checkpoint := M.copy (| γ0_0 |) in
                      let~ _ :=
                        M.write (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "revm_interpreter::interpreter::shared_memory::SharedMemory",
                            "last_checkpoint"
                          |),
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::option::Option") [] [ Ty.path "usize" ],
                              "unwrap_or_default",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "core::option::Option")
                                    []
                                    [ Ty.apply (Ty.path "&") [] [ Ty.path "usize" ] ],
                                  "cloned",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ Ty.path "usize" ],
                                      "last",
                                      []
                                    |),
                                    [
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::ops::deref::Deref",
                                          Ty.apply
                                            (Ty.path "alloc::vec::Vec")
                                            []
                                            [ Ty.path "usize"; Ty.path "alloc::alloc::Global" ],
                                          [],
                                          "deref",
                                          []
                                        |),
                                        [
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "revm_interpreter::interpreter::shared_memory::SharedMemory",
                                            "checkpoints"
                                          |)
                                        ]
                                      |)
                                    ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "alloc::vec::Vec")
                                []
                                [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                              "set_len",
                              []
                            |),
                            [
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "revm_interpreter::interpreter::shared_memory::SharedMemory",
                                "buffer"
                              |);
                              M.read (| old_checkpoint |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_free_context :
        M.IsAssociatedFunction Self "free_context" free_context.
      
      (*
          pub fn len(&self) -> usize {
              self.buffer.len() - self.last_checkpoint
          }
      *)
      Definition len (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            BinOp.Wrap.sub (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply
                    (Ty.path "alloc::vec::Vec")
                    []
                    [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                  "len",
                  []
                |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "revm_interpreter::interpreter::shared_memory::SharedMemory",
                    "buffer"
                  |)
                ]
              |),
              M.read (|
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "revm_interpreter::interpreter::shared_memory::SharedMemory",
                  "last_checkpoint"
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_len : M.IsAssociatedFunction Self "len" len.
      
      (*
          pub fn is_empty(&self) -> bool {
              self.len() == 0
          }
      *)
      Definition is_empty (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            BinOp.eq (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                  "len",
                  []
                |),
                [ M.read (| self |) ]
              |),
              Value.Integer IntegerKind.Usize 0
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_empty : M.IsAssociatedFunction Self "is_empty" is_empty.
      
      (*
          pub fn current_expansion_cost(&self) -> u64 {
              crate::gas::memory_gas_for_len(self.len())
          }
      *)
      Definition current_expansion_cost (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_function (| "revm_interpreter::gas::calc::memory_gas_for_len", [] |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                    "len",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_current_expansion_cost :
        M.IsAssociatedFunction Self "current_expansion_cost" current_expansion_cost.
      
      (*
          pub fn resize(&mut self, new_size: usize) {
              self.buffer.resize(self.last_checkpoint + new_size, 0);
          }
      *)
      Definition resize (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; new_size ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let new_size := M.alloc (| new_size |) in
            M.read (|
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                      "resize",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "buffer"
                      |);
                      BinOp.Wrap.add (|
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "revm_interpreter::interpreter::shared_memory::SharedMemory",
                            "last_checkpoint"
                          |)
                        |),
                        M.read (| new_size |)
                      |);
                      Value.Integer IntegerKind.U8 0
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_resize : M.IsAssociatedFunction Self "resize" resize.
      
      (*
          pub fn slice(&self, offset: usize, size: usize) -> &[u8] {
              self.slice_range(offset..offset + size)
          }
      *)
      Definition slice (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; size ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let size := M.alloc (| size |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                "slice_range",
                []
              |),
              [
                M.read (| self |);
                Value.StructRecord
                  "core::ops::range::Range"
                  [
                    ("start", M.read (| offset |));
                    ("end_", BinOp.Wrap.add (| M.read (| offset |), M.read (| size |) |))
                  ]
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_slice : M.IsAssociatedFunction Self "slice" slice.
      
      (*
          pub fn slice_range(&self, range @ Range { start, end }: Range<usize>) -> &[u8] {
              match self.context_memory().get(range) {
                  Some(slice) => slice,
                  None => debug_unreachable!("slice OOB: {start}..{end}; len: {}", self.len()),
              }
          }
      *)
      Definition slice_range (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; β1 ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let β1 := M.alloc (| β1 |) in
            M.match_operator (|
              β1,
              [
                fun γ =>
                  ltac:(M.monadic
                    (let range := M.copy (| γ |) in
                    let γ1_0 :=
                      M.SubPointer.get_struct_record_field (|
                        γ,
                        "core::ops::range::Range",
                        "start"
                      |) in
                    let γ1_1 :=
                      M.SubPointer.get_struct_record_field (|
                        γ,
                        "core::ops::range::Range",
                        "end"
                      |) in
                    let start := M.copy (| γ1_0 |) in
                    let end_ := M.copy (| γ1_1 |) in
                    M.read (|
                      M.match_operator (|
                        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
                                    "revm_interpreter::interpreter::shared_memory::SharedMemory",
                                  "context_memory",
                                  []
                                |),
                                [ M.read (| self |) ]
                              |);
                              M.read (| range |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let slice := M.copy (| γ0_0 |) in
                              M.alloc (| M.read (| slice |) |)));
                          fun γ =>
                            ltac:(M.monadic
                              (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ := M.use (M.alloc (| Value.Bool true |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.alloc (|
                                        M.never_to_any (|
                                          M.call_closure (|
                                            M.get_function (| "core::panicking::panic_fmt", [] |),
                                            [
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "core::fmt::Arguments",
                                                  "new_v1",
                                                  []
                                                |),
                                                [
                                                  M.alloc (|
                                                    Value.Array
                                                      [
                                                        M.read (|
                                                          Value.String
                                                            "internal error: entered unreachable code: slice OOB: "
                                                        |);
                                                        M.read (| Value.String ".." |);
                                                        M.read (| Value.String "; len: " |)
                                                      ]
                                                  |);
                                                  M.match_operator (|
                                                    M.alloc (|
                                                      Value.Tuple
                                                        [
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path
                                                                  "revm_interpreter::interpreter::shared_memory::SharedMemory",
                                                                "len",
                                                                []
                                                              |),
                                                              [ M.read (| self |) ]
                                                            |)
                                                          |);
                                                          start;
                                                          end_
                                                        ]
                                                    |),
                                                    [
                                                      fun γ =>
                                                        ltac:(M.monadic
                                                          (let args := M.copy (| γ |) in
                                                          M.alloc (|
                                                            Value.Array
                                                              [
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path
                                                                      "core::fmt::rt::Argument",
                                                                    "new_display",
                                                                    [ Ty.path "usize" ]
                                                                  |),
                                                                  [
                                                                    M.read (|
                                                                      M.SubPointer.get_tuple_field (|
                                                                        args,
                                                                        1
                                                                      |)
                                                                    |)
                                                                  ]
                                                                |);
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path
                                                                      "core::fmt::rt::Argument",
                                                                    "new_display",
                                                                    [ Ty.path "usize" ]
                                                                  |),
                                                                  [
                                                                    M.read (|
                                                                      M.SubPointer.get_tuple_field (|
                                                                        args,
                                                                        2
                                                                      |)
                                                                    |)
                                                                  ]
                                                                |);
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path
                                                                      "core::fmt::rt::Argument",
                                                                    "new_display",
                                                                    [ Ty.path "usize" ]
                                                                  |),
                                                                  [
                                                                    M.read (|
                                                                      M.SubPointer.get_tuple_field (|
                                                                        args,
                                                                        0
                                                                      |)
                                                                    |)
                                                                  ]
                                                                |)
                                                              ]
                                                          |)))
                                                    ]
                                                  |)
                                                ]
                                              |)
                                            ]
                                          |)
                                        |)
                                      |)));
                                  fun γ =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            let~ _ :=
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.call_closure (|
                                                    M.get_function (|
                                                      "core::hint::unreachable_unchecked",
                                                      []
                                                    |),
                                                    []
                                                  |)
                                                |)
                                              |) in
                                            M.alloc (| Value.Tuple [] |)
                                          |)
                                        |)
                                      |)))
                                ]
                              |)))
                        ]
                      |)
                    |)))
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_slice_range : M.IsAssociatedFunction Self "slice_range" slice_range.
      
      (*
          pub fn slice_mut(&mut self, offset: usize, size: usize) -> &mut [u8] {
              let end = offset + size;
              match self.context_memory_mut().get_mut(offset..end) {
                  Some(slice) => slice,
                  None => debug_unreachable!("slice OOB: {offset}..{end}"),
              }
          }
      *)
      Definition slice_mut (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; size ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let size := M.alloc (| size |) in
            M.read (|
              let~ end_ :=
                M.alloc (| BinOp.Wrap.add (| M.read (| offset |), M.read (| size |) |) |) in
              M.alloc (|
                M.read (|
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                          "get_mut",
                          [ Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ] ]
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                              "context_memory_mut",
                              []
                            |),
                            [ M.read (| self |) ]
                          |);
                          Value.StructRecord
                            "core::ops::range::Range"
                            [ ("start", M.read (| offset |)); ("end_", M.read (| end_ |)) ]
                        ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::option::Option::Some",
                              0
                            |) in
                          let slice := M.copy (| γ0_0 |) in
                          M.alloc (| M.read (| slice |) |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ := M.use (M.alloc (| Value.Bool true |)) in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  M.alloc (|
                                    M.never_to_any (|
                                      M.call_closure (|
                                        M.get_function (| "core::panicking::panic_fmt", [] |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "core::fmt::Arguments",
                                              "new_v1",
                                              []
                                            |),
                                            [
                                              M.alloc (|
                                                Value.Array
                                                  [
                                                    M.read (|
                                                      Value.String
                                                        "internal error: entered unreachable code: slice OOB: "
                                                    |);
                                                    M.read (| Value.String ".." |)
                                                  ]
                                              |);
                                              M.alloc (|
                                                Value.Array
                                                  [
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "core::fmt::rt::Argument",
                                                        "new_display",
                                                        [ Ty.path "usize" ]
                                                      |),
                                                      [ offset ]
                                                    |);
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "core::fmt::rt::Argument",
                                                        "new_display",
                                                        [ Ty.path "usize" ]
                                                      |),
                                                      [ end_ ]
                                                    |)
                                                  ]
                                              |)
                                            ]
                                          |)
                                        ]
                                      |)
                                    |)
                                  |)));
                              fun γ =>
                                ltac:(M.monadic
                                  (M.alloc (|
                                    M.never_to_any (|
                                      M.read (|
                                        let~ _ :=
                                          M.alloc (|
                                            M.never_to_any (|
                                              M.call_closure (|
                                                M.get_function (|
                                                  "core::hint::unreachable_unchecked",
                                                  []
                                                |),
                                                []
                                              |)
                                            |)
                                          |) in
                                        M.alloc (| Value.Tuple [] |)
                                      |)
                                    |)
                                  |)))
                            ]
                          |)))
                    ]
                  |)
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_slice_mut : M.IsAssociatedFunction Self "slice_mut" slice_mut.
      
      (*
          pub fn get_byte(&self, offset: usize) -> u8 {
              self.slice(offset, 1)[0]
          }
      *)
      Definition get_byte (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            M.read (|
              M.SubPointer.get_array_field (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                    "slice",
                    []
                  |),
                  [ M.read (| self |); M.read (| offset |); Value.Integer IntegerKind.Usize 1 ]
                |),
                M.alloc (| Value.Integer IntegerKind.Usize 0 |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_get_byte : M.IsAssociatedFunction Self "get_byte" get_byte.
      
      (*
          pub fn get_word(&self, offset: usize) -> B256 {
              self.slice(offset, 32).try_into().unwrap()
          }
      *)
      Definition get_word (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply
                  (Ty.path "core::result::Result")
                  []
                  [
                    Ty.apply
                      (Ty.path "alloy_primitives::bits::fixed::FixedBytes")
                      [ Value.Integer IntegerKind.Usize 32 ]
                      [];
                    Ty.path "core::array::TryFromSliceError"
                  ],
                "unwrap",
                []
              |),
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::convert::TryInto",
                    Ty.apply (Ty.path "&") [] [ Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ] ],
                    [
                      Ty.apply
                        (Ty.path "alloy_primitives::bits::fixed::FixedBytes")
                        [ Value.Integer IntegerKind.Usize 32 ]
                        []
                    ],
                    "try_into",
                    []
                  |),
                  [
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "slice",
                        []
                      |),
                      [ M.read (| self |); M.read (| offset |); Value.Integer IntegerKind.Usize 32 ]
                    |)
                  ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_get_word : M.IsAssociatedFunction Self "get_word" get_word.
      
      (*
          pub fn get_u256(&self, offset: usize) -> U256 {
              self.get_word(offset).into()
          }
      *)
      Definition get_u256 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::convert::Into",
                Ty.apply
                  (Ty.path "alloy_primitives::bits::fixed::FixedBytes")
                  [ Value.Integer IntegerKind.Usize 32 ]
                  [],
                [
                  Ty.apply
                    (Ty.path "ruint::Uint")
                    [ Value.Integer IntegerKind.Usize 256; Value.Integer IntegerKind.Usize 4 ]
                    []
                ],
                "into",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                    "get_word",
                    []
                  |),
                  [ M.read (| self |); M.read (| offset |) ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_get_u256 : M.IsAssociatedFunction Self "get_u256" get_u256.
      
      (*
          pub fn set_byte(&mut self, offset: usize, byte: u8) {
              self.set(offset, &[byte]);
          }
      *)
      Definition set_byte (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; byte ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let byte := M.alloc (| byte |) in
            M.read (|
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                      "set",
                      []
                    |),
                    [
                      M.read (| self |);
                      M.read (| offset |);
                      M.alloc (| Value.Array [ M.read (| byte |) ] |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_set_byte : M.IsAssociatedFunction Self "set_byte" set_byte.
      
      (*
          pub fn set_word(&mut self, offset: usize, value: &B256) {
              self.set(offset, &value[..]);
          }
      *)
      Definition set_word (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; value ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let value := M.alloc (| value |) in
            M.read (|
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                      "set",
                      []
                    |),
                    [
                      M.read (| self |);
                      M.read (| offset |);
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::ops::index::Index",
                          Ty.apply
                            (Ty.path "alloy_primitives::bits::fixed::FixedBytes")
                            [ Value.Integer IntegerKind.Usize 32 ]
                            [],
                          [ Ty.path "core::ops::range::RangeFull" ],
                          "index",
                          []
                        |),
                        [ M.read (| value |); Value.StructTuple "core::ops::range::RangeFull" [] ]
                      |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_set_word : M.IsAssociatedFunction Self "set_word" set_word.
      
      (*
          pub fn set_u256(&mut self, offset: usize, value: U256) {
              self.set(offset, &value.to_be_bytes::<32>());
          }
      *)
      Definition set_u256 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; value ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let value := M.alloc (| value |) in
            M.read (|
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                      "set",
                      []
                    |),
                    [
                      M.read (| self |);
                      M.read (| offset |);
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply
                              (Ty.path "ruint::Uint")
                              [
                                Value.Integer IntegerKind.Usize 256;
                                Value.Integer IntegerKind.Usize 4
                              ]
                              [],
                            "to_be_bytes",
                            []
                          |),
                          [ value ]
                        |)
                      |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_set_u256 : M.IsAssociatedFunction Self "set_u256" set_u256.
      
      (*
          pub fn set(&mut self, offset: usize, value: &[u8]) {
              if !value.is_empty() {
                  self.slice_mut(offset, value.len()).copy_from_slice(value);
              }
          }
      *)
      Definition set (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; value ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let value := M.alloc (| value |) in
            M.read (|
              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.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                  "is_empty",
                                  []
                                |),
                                [ M.read (| value |) ]
                              |)
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                              "copy_from_slice",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path
                                    "revm_interpreter::interpreter::shared_memory::SharedMemory",
                                  "slice_mut",
                                  []
                                |),
                                [
                                  M.read (| self |);
                                  M.read (| offset |);
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                      "len",
                                      []
                                    |),
                                    [ M.read (| value |) ]
                                  |)
                                ]
                              |);
                              M.read (| value |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_set : M.IsAssociatedFunction Self "set" set.
      
      (*
          pub fn set_data(&mut self, memory_offset: usize, data_offset: usize, len: usize, data: &[u8]) {
              if data_offset >= data.len() {
                  // nullify all memory slots
                  self.slice_mut(memory_offset, len).fill(0);
                  return;
              }
              let data_end = min(data_offset + len, data.len());
              let data_len = data_end - data_offset;
              debug_assert!(data_offset < data.len() && data_end <= data.len());
              let data = unsafe { data.get_unchecked(data_offset..data_end) };
              self.slice_mut(memory_offset, data_len)
                  .copy_from_slice(data);
      
              // nullify rest of memory slots
              // SAFETY: Memory is assumed to be valid, and it is commented where this assumption is made.
              self.slice_mut(memory_offset + data_len, len - data_len)
                  .fill(0);
          }
      *)
      Definition set_data (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; memory_offset; data_offset; len; data ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let memory_offset := M.alloc (| memory_offset |) in
            let data_offset := M.alloc (| data_offset |) in
            let len := M.alloc (| len |) in
            let data := M.alloc (| data |) 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.ge (|
                                    M.read (| data_offset |),
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                        "len",
                                        []
                                      |),
                                      [ M.read (| data |) ]
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  let~ _ :=
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                          "fill",
                                          []
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path
                                                "revm_interpreter::interpreter::shared_memory::SharedMemory",
                                              "slice_mut",
                                              []
                                            |),
                                            [
                                              M.read (| self |);
                                              M.read (| memory_offset |);
                                              M.read (| len |)
                                            ]
                                          |);
                                          Value.Integer IntegerKind.U8 0
                                        ]
                                      |)
                                    |) in
                                  M.return_ (| Value.Tuple [] |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ data_end :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_function (| "core::cmp::min", [ Ty.path "usize" ] |),
                        [
                          BinOp.Wrap.add (| M.read (| data_offset |), M.read (| len |) |);
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                              "len",
                              []
                            |),
                            [ M.read (| data |) ]
                          |)
                        ]
                      |)
                    |) in
                  let~ data_len :=
                    M.alloc (|
                      BinOp.Wrap.sub (| M.read (| data_end |), M.read (| data_offset |) |)
                    |) 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 (|
                                              LogicalOp.and (|
                                                BinOp.lt (|
                                                  M.read (| data_offset |),
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "slice")
                                                        []
                                                        [ Ty.path "u8" ],
                                                      "len",
                                                      []
                                                    |),
                                                    [ M.read (| data |) ]
                                                  |)
                                                |),
                                                ltac:(M.monadic
                                                  (BinOp.le (|
                                                    M.read (| data_end |),
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.apply
                                                          (Ty.path "slice")
                                                          []
                                                          [ Ty.path "u8" ],
                                                        "len",
                                                        []
                                                      |),
                                                      [ M.read (| data |) ]
                                                    |)
                                                  |)))
                                              |)
                                            |)
                                          |)) 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: data_offset < data.len() && data_end <= data.len()"
                                              |)
                                            ]
                                          |)
                                        |)
                                      |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            M.alloc (| Value.Tuple [] |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ data :=
                    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::Range") [] [ Ty.path "usize" ] ]
                        |),
                        [
                          M.read (| data |);
                          Value.StructRecord
                            "core::ops::range::Range"
                            [ ("start", M.read (| data_offset |)); ("end_", M.read (| data_end |)) ]
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                          "copy_from_slice",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                              "slice_mut",
                              []
                            |),
                            [ M.read (| self |); M.read (| memory_offset |); M.read (| data_len |) ]
                          |);
                          M.read (| data |)
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                          "fill",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                              "slice_mut",
                              []
                            |),
                            [
                              M.read (| self |);
                              BinOp.Wrap.add (|
                                M.read (| memory_offset |),
                                M.read (| data_len |)
                              |);
                              BinOp.Wrap.sub (| M.read (| len |), M.read (| data_len |) |)
                            ]
                          |);
                          Value.Integer IntegerKind.U8 0
                        ]
                      |)
                    |) in
                  M.alloc (| Value.Tuple [] |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_set_data : M.IsAssociatedFunction Self "set_data" set_data.
      
      (*
          pub fn copy(&mut self, dst: usize, src: usize, len: usize) {
              self.context_memory_mut().copy_within(src..src + len, dst);
          }
      *)
      Definition copy (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; dst; src; len ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let dst := M.alloc (| dst |) in
            let src := M.alloc (| src |) in
            let len := M.alloc (| len |) in
            M.read (|
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                      "copy_within",
                      [ Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ] ]
                    |),
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "revm_interpreter::interpreter::shared_memory::SharedMemory",
                          "context_memory_mut",
                          []
                        |),
                        [ M.read (| self |) ]
                      |);
                      Value.StructRecord
                        "core::ops::range::Range"
                        [
                          ("start", M.read (| src |));
                          ("end_", BinOp.Wrap.add (| M.read (| src |), M.read (| len |) |))
                        ];
                      M.read (| dst |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_copy : M.IsAssociatedFunction Self "copy" copy.
      
      (*
          pub fn context_memory(&self) -> &[u8] {
              // SAFETY: access bounded by buffer length
              unsafe {
                  self.buffer
                      .get_unchecked(self.last_checkpoint..self.buffer.len())
              }
          }
      *)
      Definition context_memory (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                "get_unchecked",
                [ Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ] ]
              |),
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::ops::deref::Deref",
                    Ty.apply
                      (Ty.path "alloc::vec::Vec")
                      []
                      [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                    [],
                    "deref",
                    []
                  |),
                  [
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "revm_interpreter::interpreter::shared_memory::SharedMemory",
                      "buffer"
                    |)
                  ]
                |);
                Value.StructRecord
                  "core::ops::range::Range"
                  [
                    ("start",
                      M.read (|
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "revm_interpreter::interpreter::shared_memory::SharedMemory",
                          "last_checkpoint"
                        |)
                      |));
                    ("end_",
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            []
                            [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                          "len",
                          []
                        |),
                        [
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "revm_interpreter::interpreter::shared_memory::SharedMemory",
                            "buffer"
                          |)
                        ]
                      |))
                  ]
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_context_memory :
        M.IsAssociatedFunction Self "context_memory" context_memory.
      
      (*
          pub fn context_memory_mut(&mut self) -> &mut [u8] {
              let buf_len = self.buffer.len();
              // SAFETY: access bounded by buffer length
              unsafe { self.buffer.get_unchecked_mut(self.last_checkpoint..buf_len) }
          }
      *)
      Definition context_memory_mut (ε : 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~ buf_len :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                      "len",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "revm_interpreter::interpreter::shared_memory::SharedMemory",
                        "buffer"
                      |)
                    ]
                  |)
                |) in
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                    "get_unchecked_mut",
                    [ Ty.apply (Ty.path "core::ops::range::Range") [] [ Ty.path "usize" ] ]
                  |),
                  [
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::ops::deref::DerefMut",
                        Ty.apply
                          (Ty.path "alloc::vec::Vec")
                          []
                          [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                        [],
                        "deref_mut",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "revm_interpreter::interpreter::shared_memory::SharedMemory",
                          "buffer"
                        |)
                      ]
                    |);
                    Value.StructRecord
                      "core::ops::range::Range"
                      [
                        ("start",
                          M.read (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "revm_interpreter::interpreter::shared_memory::SharedMemory",
                              "last_checkpoint"
                            |)
                          |));
                        ("end_", M.read (| buf_len |))
                      ]
                  ]
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_context_memory_mut :
        M.IsAssociatedFunction Self "context_memory_mut" context_memory_mut.
    End Impl_revm_interpreter_interpreter_shared_memory_SharedMemory.
    
    (*
    pub const fn num_words(len: u64) -> u64 {
        len.saturating_add(31) / 32
    }
    *)
    Definition num_words (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ len ] =>
        ltac:(M.monadic
          (let len := M.alloc (| len |) in
          BinOp.Wrap.div (|
            M.call_closure (|
              M.get_associated_function (| Ty.path "u64", "saturating_add", [] |),
              [ M.read (| len |); Value.Integer IntegerKind.U64 31 ]
            |),
            Value.Integer IntegerKind.U64 32
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_num_words :
      M.IsFunction "revm_interpreter::interpreter::shared_memory::num_words" num_words.
  End shared_memory.
End interpreter.
